LLVM 24.0.0git
AddressSanitizer.cpp
Go to the documentation of this file.
1//===- AddressSanitizer.cpp - memory 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// This file is a part of AddressSanitizer, an address basic correctness
10// checker.
11// Details of the algorithm:
12// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
13//
14// FIXME: This sanitizer does not yet handle scalable vectors
15//
16//===----------------------------------------------------------------------===//
17
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMap.h"
25#include "llvm/ADT/Statistic.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/Twine.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/Attributes.h"
39#include "llvm/IR/BasicBlock.h"
40#include "llvm/IR/Comdat.h"
41#include "llvm/IR/Constant.h"
42#include "llvm/IR/Constants.h"
43#include "llvm/IR/DIBuilder.h"
44#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/DebugLoc.h"
49#include "llvm/IR/Function.h"
50#include "llvm/IR/GlobalAlias.h"
51#include "llvm/IR/GlobalValue.h"
53#include "llvm/IR/IRBuilder.h"
54#include "llvm/IR/InlineAsm.h"
55#include "llvm/IR/InstVisitor.h"
56#include "llvm/IR/InstrTypes.h"
57#include "llvm/IR/Instruction.h"
60#include "llvm/IR/Intrinsics.h"
61#include "llvm/IR/LLVMContext.h"
62#include "llvm/IR/MDBuilder.h"
63#include "llvm/IR/Metadata.h"
64#include "llvm/IR/Module.h"
65#include "llvm/IR/Type.h"
66#include "llvm/IR/Use.h"
67#include "llvm/IR/Value.h"
70#include "llvm/Support/Debug.h"
73#include "llvm/Support/ModRef.h"
84#include <algorithm>
85#include <cassert>
86#include <cstddef>
87#include <cstdint>
88#include <iomanip>
89#include <limits>
90#include <sstream>
91#include <string>
92#include <tuple>
93#include <utility>
94
95using namespace llvm;
96
97#define DEBUG_TYPE "asan"
98
100static const uint64_t kDefaultShadowOffset32 = 1ULL << 29;
101static const uint64_t kDefaultShadowOffset64 = 1ULL << 44;
103 std::numeric_limits<uint64_t>::max();
104static const uint64_t kSmallX86_64ShadowOffsetBase = 0x7FFFFFFF; // < 2G.
106static const uint64_t kLinuxKasan_ShadowOffset64 = 0xdffffc0000000000;
107static const uint64_t kPPC64_ShadowOffset64 = 1ULL << 44;
108static const uint64_t kSystemZ_ShadowOffset64 = 1ULL << 52;
109static const uint64_t kMIPS_ShadowOffsetN32 = 1ULL << 29;
110static const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000;
111static const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37;
112static const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36;
113static const uint64_t kLoongArch64_ShadowOffset64 = 1ULL << 46;
115static const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30;
116static const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46;
117static const uint64_t kFreeBSDAArch64_ShadowOffset64 = 1ULL << 47;
118static const uint64_t kFreeBSDKasan_ShadowOffset64 = 0xdffff7c000000000;
119static const uint64_t kNetBSD_ShadowOffset32 = 1ULL << 30;
120static const uint64_t kNetBSD_ShadowOffset64 = 1ULL << 46;
121static const uint64_t kNetBSDKasan_ShadowOffset64 = 0xdfff900000000000;
122static const uint64_t kPS_ShadowOffset64 = 1ULL << 40;
123static const uint64_t kWindowsShadowOffset32 = 3ULL << 28;
125
126// The shadow memory space is dynamically allocated.
128
129static const size_t kMinStackMallocSize = 1 << 6; // 64B
130static const size_t kMaxStackMallocSize = 1 << 16; // 64K
131static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
132static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
133
134const char kAsanModuleCtorName[] = "asan.module_ctor";
135const char kAsanModuleDtorName[] = "asan.module_dtor";
137// On Emscripten, the system needs more than one priorities for constructors.
139const char kAsanReportErrorTemplate[] = "__asan_report_";
140const char kAsanRegisterGlobalsName[] = "__asan_register_globals";
141const char kAsanUnregisterGlobalsName[] = "__asan_unregister_globals";
142const char kAsanRegisterImageGlobalsName[] = "__asan_register_image_globals";
144 "__asan_unregister_image_globals";
145const char kAsanRegisterElfGlobalsName[] = "__asan_register_elf_globals";
146const char kAsanUnregisterElfGlobalsName[] = "__asan_unregister_elf_globals";
147const char kAsanPoisonGlobalsName[] = "__asan_before_dynamic_init";
148const char kAsanUnpoisonGlobalsName[] = "__asan_after_dynamic_init";
149const char kAsanInitName[] = "__asan_init";
150const char kAsanVersionCheckNamePrefix[] = "__asan_version_mismatch_check_v";
151const char kAsanPtrCmp[] = "__sanitizer_ptr_cmp";
152const char kAsanPtrSub[] = "__sanitizer_ptr_sub";
153const char kAsanHandleNoReturnName[] = "__asan_handle_no_return";
154static const int kMaxAsanStackMallocSizeClass = 10;
155const char kAsanStackMallocNameTemplate[] = "__asan_stack_malloc_";
157 "__asan_stack_malloc_always_";
158const char kAsanStackFreeNameTemplate[] = "__asan_stack_free_";
159const char kAsanGenPrefix[] = "___asan_gen_";
160const char kODRGenPrefix[] = "__odr_asan_gen_";
161const char kSanCovGenPrefix[] = "__sancov_gen_";
162const char kAsanSetShadowPrefix[] = "__asan_set_shadow_";
163const char kAsanPoisonStackMemoryName[] = "__asan_poison_stack_memory";
164const char kAsanUnpoisonStackMemoryName[] = "__asan_unpoison_stack_memory";
165
166// ASan version script has __asan_* wildcard. Triple underscore prevents a
167// linker (gold) warning about attempting to export a local symbol.
168const char kAsanGlobalsRegisteredFlagName[] = "___asan_globals_registered";
169
171 "__asan_option_detect_stack_use_after_return";
172
174 "__asan_shadow_memory_dynamic_address";
175
176const char kAsanAllocaPoison[] = "__asan_alloca_poison";
177const char kAsanAllocasUnpoison[] = "__asan_allocas_unpoison";
178
179const char kAMDGPUAddressSharedName[] = "llvm.amdgcn.is.shared";
180const char kAMDGPUAddressPrivateName[] = "llvm.amdgcn.is.private";
181const char kAMDGPUBallotName[] = "llvm.amdgcn.ballot.i64";
182const char kAMDGPUUnreachableName[] = "llvm.amdgcn.unreachable";
183
184// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
185static const size_t kNumberOfAccessSizes = 5;
186
187static const uint64_t kAllocaRzSize = 32;
188
189// ASanAccessInfo implementation constants.
190constexpr size_t kCompileKernelShift = 0;
191constexpr size_t kCompileKernelMask = 0x1;
192constexpr size_t kAccessSizeIndexShift = 1;
193constexpr size_t kAccessSizeIndexMask = 0xf;
194constexpr size_t kIsWriteShift = 5;
195constexpr size_t kIsWriteMask = 0x1;
196
197STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
198STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
199STATISTIC(NumOptimizedAccessesToGlobalVar,
200 "Number of optimized accesses to global vars");
201STATISTIC(NumOptimizedAccessesToStackVar,
202 "Number of optimized accesses to stack vars");
203
204namespace {
205
206/// This struct defines the shadow mapping using the rule:
207/// shadow = (mem >> Scale) ADD-or-OR Offset.
208/// If InGlobal is true, then
209/// extern char __asan_shadow[];
210/// shadow = (mem >> Scale) + &__asan_shadow
211struct ShadowMapping {
212 int Scale;
214 bool OrShadowOffset;
215 bool InGlobal;
216};
217
218} // end anonymous namespace
219
220static ShadowMapping getShadowMapping(const InstrumentationOptions &Opts,
221 const Triple &TargetTriple, int LongSize,
222 bool IsKasan) {
223 bool IsAndroid = TargetTriple.isAndroid();
224 bool IsIOS = TargetTriple.isiOS() || TargetTriple.isWatchOS() ||
225 TargetTriple.isDriverKit();
226 bool IsMacOS = TargetTriple.isMacOSX();
227 bool IsFreeBSD = TargetTriple.isOSFreeBSD();
228 bool IsNetBSD = TargetTriple.isOSNetBSD();
229 bool IsPS = TargetTriple.isPS();
230 bool IsLinux = TargetTriple.isOSLinux();
231 bool IsPPC64 = TargetTriple.getArch() == Triple::ppc64 ||
232 TargetTriple.getArch() == Triple::ppc64le;
233 bool IsSystemZ = TargetTriple.getArch() == Triple::systemz;
234 bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
235 bool IsMIPSN32ABI = TargetTriple.isABIN32();
236 bool IsMIPS32 = TargetTriple.isMIPS32();
237 bool IsMIPS64 = TargetTriple.isMIPS64();
238 bool IsArmOrThumb = TargetTriple.isARM() || TargetTriple.isThumb();
239 bool IsAArch64 = TargetTriple.getArch() == Triple::aarch64 ||
240 TargetTriple.getArch() == Triple::aarch64_be;
241 bool IsLoongArch64 = TargetTriple.isLoongArch64();
242 bool IsRISCV64 = TargetTriple.getArch() == Triple::riscv64;
243 bool IsWindows = TargetTriple.isOSWindows();
244 bool IsFuchsia = TargetTriple.isOSFuchsia();
245 bool IsAMDGPU = TargetTriple.isAMDGPU();
246 bool IsHaiku = TargetTriple.isOSHaiku();
247 bool IsWasm = TargetTriple.isWasm();
248 bool IsBPF = TargetTriple.isBPF();
249
250 ShadowMapping Mapping;
251
252 Mapping.Scale = Opts.asan_mapping_scale.value_or(kDefaultShadowScale);
253
254 if (LongSize == 32) {
255 if (IsAndroid)
256 Mapping.Offset = kDynamicShadowSentinel;
257 else if (IsMIPSN32ABI)
258 Mapping.Offset = kMIPS_ShadowOffsetN32;
259 else if (IsMIPS32)
260 Mapping.Offset = kMIPS32_ShadowOffset32;
261 else if (IsFreeBSD)
262 Mapping.Offset = kFreeBSD_ShadowOffset32;
263 else if (IsNetBSD)
264 Mapping.Offset = kNetBSD_ShadowOffset32;
265 else if (IsIOS)
266 Mapping.Offset = kDynamicShadowSentinel;
267 else if (IsWindows)
268 Mapping.Offset = kWindowsShadowOffset32;
269 else if (IsWasm)
270 Mapping.Offset = kWebAssemblyShadowOffset;
271 else
272 Mapping.Offset = kDefaultShadowOffset32;
273 } else { // LongSize == 64
274 // Fuchsia is always PIE, which means that the beginning of the address
275 // space is always available.
276 if (IsFuchsia) {
277 // kDynamicShadowSentinel tells instrumentation to use the dynamic shadow.
278 Mapping.Offset = kDynamicShadowSentinel;
279 } else if (IsPPC64)
280 Mapping.Offset = kPPC64_ShadowOffset64;
281 else if (IsSystemZ)
282 Mapping.Offset = kSystemZ_ShadowOffset64;
283 else if (IsFreeBSD && IsAArch64)
284 Mapping.Offset = kFreeBSDAArch64_ShadowOffset64;
285 else if (IsFreeBSD && !IsMIPS64) {
286 if (IsKasan)
287 Mapping.Offset = kFreeBSDKasan_ShadowOffset64;
288 else
289 Mapping.Offset = kFreeBSD_ShadowOffset64;
290 } else if (IsNetBSD) {
291 if (IsKasan)
292 Mapping.Offset = kNetBSDKasan_ShadowOffset64;
293 else
294 Mapping.Offset = kNetBSD_ShadowOffset64;
295 } else if (IsPS)
296 Mapping.Offset = kPS_ShadowOffset64;
297 else if (IsLinux && IsX86_64) {
298 if (IsKasan)
299 Mapping.Offset = kLinuxKasan_ShadowOffset64;
300 else
301 Mapping.Offset = (kSmallX86_64ShadowOffsetBase &
302 (kSmallX86_64ShadowOffsetAlignMask << Mapping.Scale));
303 } else if (IsWindows && (IsX86_64 || IsAArch64)) {
304 Mapping.Offset = kWindowsShadowOffset64;
305 } else if (IsMIPS64)
306 Mapping.Offset = kMIPS64_ShadowOffset64;
307 else if (IsIOS)
308 Mapping.Offset = kDynamicShadowSentinel;
309 else if (IsMacOS && IsAArch64)
310 Mapping.Offset = kDynamicShadowSentinel;
311 else if (IsAArch64)
312 Mapping.Offset = kAArch64_ShadowOffset64;
313 else if (IsLoongArch64)
314 Mapping.Offset = kLoongArch64_ShadowOffset64;
315 else if (IsRISCV64)
316 Mapping.Offset = kRISCV64_ShadowOffset64;
317 else if (IsAMDGPU)
318 Mapping.Offset = (kSmallX86_64ShadowOffsetBase &
319 (kSmallX86_64ShadowOffsetAlignMask << Mapping.Scale));
320 else if (IsHaiku && IsX86_64)
321 Mapping.Offset = (kSmallX86_64ShadowOffsetBase &
322 (kSmallX86_64ShadowOffsetAlignMask << Mapping.Scale));
323 else if (IsBPF)
324 Mapping.Offset = kDynamicShadowSentinel;
325 else if (IsWasm)
326 Mapping.Offset = kWebAssemblyShadowOffset;
327 else
328 Mapping.Offset = kDefaultShadowOffset64;
329 }
330
331 if (Opts.asan_force_dynamic_shadow) {
332 Mapping.Offset = kDynamicShadowSentinel;
333 }
334
335 if (Opts.asan_mapping_offset) {
336 Mapping.Offset = *Opts.asan_mapping_offset;
337 }
338
339 // OR-ing shadow offset if more efficient (at least on x86) if the offset
340 // is a power of two, but on ppc64 and loongarch64 we have to use add since
341 // the shadow offset is not necessarily 1/8-th of the address space. On
342 // SystemZ, we could OR the constant in a single instruction, but it's more
343 // efficient to load it once and use indexed addressing.
344 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
345 !IsRISCV64 && !IsLoongArch64 &&
346 !(Mapping.Offset & (Mapping.Offset - 1)) &&
347 Mapping.Offset != kDynamicShadowSentinel;
348 Mapping.InGlobal = Opts.asan_with_ifunc && IsAndroid && IsArmOrThumb;
349
350 return Mapping;
351}
352
353void llvm::getAddressSanitizerParams(const Triple &TargetTriple, int LongSize,
354 bool IsKasan, uint64_t *ShadowBase,
355 int *MappingScale, bool *OrShadowOffset) {
356 auto Mapping = getShadowMapping(InstrumentationOptions::Global, TargetTriple,
357 LongSize, IsKasan);
358 *ShadowBase = Mapping.Offset;
359 *MappingScale = Mapping.Scale;
360 *OrShadowOffset = Mapping.OrShadowOffset;
361}
362
364 // Adding sanitizer checks invalidates previously inferred memory attributes.
365 //
366 // This is not only true for sanitized functions, because AttrInfer can
367 // infer those attributes on libc functions, which is not true if those
368 // are instrumented (Android) or intercepted.
369 //
370 // We might want to model ASan shadow memory more opaquely to get rid of
371 // this problem altogether, by hiding the shadow memory write in an
372 // intrinsic, essentially like in the AArch64StackTagging pass. But that's
373 // for another day.
374
375 bool Changed = false;
376 // We add memory(readwrite) to functions that don't already have that set and
377 // can access any non-inaccessible memory. Sanitizer instrumentation can
378 // read/write shadow memory, which is IRMemLocation::Other. Sanitizer
379 // instrumentation can instrument any memory accesses to non-inaccessible
380 // memory.
381 if (!F.getMemoryEffects()
382 .getWithoutLoc(IRMemLocation::InaccessibleMem)
383 .doesNotAccessMemory() &&
384 !isModAndRefSet(F.getMemoryEffects().getModRef(IRMemLocation::Other))) {
385 F.setMemoryEffects(F.getMemoryEffects() |
387 Changed = true;
388 }
389 // HWASan reads from argument memory even for previously write-only accesses.
390 if (ReadsArgMem) {
391 if (F.getMemoryEffects().getModRef(IRMemLocation::ArgMem) ==
393 F.setMemoryEffects(F.getMemoryEffects() |
395 Changed = true;
396 }
397 for (Argument &A : F.args()) {
398 if (A.hasAttribute(Attribute::WriteOnly)) {
399 A.removeAttr(Attribute::WriteOnly);
400 Changed = true;
401 }
402 }
403 }
404 if (Changed) {
405 // nobuiltin makes sure later passes don't restore assumptions about
406 // the function.
407 F.addFnAttr(Attribute::NoBuiltin);
408 }
409}
410
416
424
425static uint64_t getRedzoneSizeForScale(int MappingScale) {
426 // Redzone used for stack and globals is at least 32 bytes.
427 // For scales 6 and 7, the redzone has to be 64 and 128 bytes respectively.
428 return std::max(32U, 1U << MappingScale);
429}
430
432 if (TargetTriple.isOSEmscripten())
434 else
436}
437
438static Twine genName(StringRef suffix) {
439 return Twine(kAsanGenPrefix) + suffix;
440}
441
442namespace {
443
444class AsanFunctionInserter {
445public:
446 AsanFunctionInserter(Module &M) : M(M) {}
447
448 template <typename... ArgTypes>
449 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
450 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
451 }
452
453private:
454 Module &M;
455};
456
457} // end anonymous namespace
458
459namespace {
460/// Helper RAII class to post-process inserted asan runtime calls during a
461/// pass on a single Function. Upon end of scope, detects and applies the
462/// required funclet OpBundle.
463class RuntimeCallInserter {
464 Function *OwnerFn = nullptr;
465 bool TrackInsertedCalls = false;
466 SmallVector<CallInst *> InsertedCalls;
467
468public:
469 RuntimeCallInserter(Function &Fn) : OwnerFn(&Fn) {
470 if (Fn.hasPersonalityFn()) {
471 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
472 if (isScopedEHPersonality(Personality))
473 TrackInsertedCalls = true;
474 }
475 }
476
477 ~RuntimeCallInserter() {
478 if (InsertedCalls.empty())
479 return;
480 assert(TrackInsertedCalls && "Calls were wrongly tracked");
481
482 DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*OwnerFn);
483 for (CallInst *CI : InsertedCalls) {
484 BasicBlock *BB = CI->getParent();
485 assert(BB && "Instruction doesn't belong to a BasicBlock");
486 assert(BB->getParent() == OwnerFn &&
487 "Instruction doesn't belong to the expected Function!");
488
489 ColorVector &Colors = BlockColors[BB];
490 // funclet opbundles are only valid in monochromatic BBs.
491 // Note that unreachable BBs are seen as colorless by colorEHFunclets()
492 // and will be DCE'ed later.
493 if (Colors.empty())
494 continue;
495 if (Colors.size() != 1) {
496 OwnerFn->getContext().emitError(
497 "Instruction's BasicBlock is not monochromatic");
498 continue;
499 }
500
501 BasicBlock *Color = Colors.front();
502 BasicBlock::iterator EHPadIt = Color->getFirstNonPHIIt();
503
504 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
505 // Replace CI with a clone with an added funclet OperandBundle
506 OperandBundleDef OB("funclet", &*EHPadIt);
508 OB, CI->getIterator());
509 NewCall->copyMetadata(*CI);
510 CI->replaceAllUsesWith(NewCall);
511 CI->eraseFromParent();
512 }
513 }
514 }
515
516 CallInst *createRuntimeCall(IRBuilder<> &IRB, FunctionCallee Callee,
517 ArrayRef<Value *> Args = {},
518 const Twine &Name = "") {
519 assert(IRB.GetInsertBlock()->getParent() == OwnerFn);
520
521 CallInst *Inst = IRB.CreateCall(Callee, Args, Name, nullptr);
522 if (TrackInsertedCalls)
523 InsertedCalls.push_back(Inst);
524 return Inst;
525 }
526};
527
528/// AddressSanitizer: instrument the code in module to find memory bugs.
529struct AddressSanitizer {
530 AddressSanitizer(const InstrumentationOptions &Opts, Module &M,
531 const StackSafetyGlobalInfo *SSGI,
532 int InstrumentationWithCallsThreshold,
533 uint32_t MaxInlinePoisoningSize, bool CompileKernel = false,
534 bool Recover = false, bool UseAfterScope = false,
535 AsanDetectStackUseAfterReturnMode UseAfterReturn =
536 AsanDetectStackUseAfterReturnMode::Runtime)
537 : Opts(Opts), M(M), Inserter(M),
538 CompileKernel(valueOr(Opts.asan_kernel, CompileKernel)),
539 Recover(valueOr(Opts.asan_recover, Recover)),
540 UseAfterScope(UseAfterScope || Opts.asan_use_after_scope),
541 UseAfterReturn(Opts.asan_use_after_return.value_or(UseAfterReturn)),
542 SSGI(SSGI), InstrumentationWithCallsThreshold(
543 Opts.asan_instrumentation_with_call_threshold.value_or(
544 InstrumentationWithCallsThreshold)),
545 MaxInlinePoisoningSize(Opts.asan_max_inline_poisoning_size.value_or(
546 MaxInlinePoisoningSize)) {
547 C = &(M.getContext());
548 DL = &M.getDataLayout();
549 LongSize = M.getDataLayout().getPointerSizeInBits();
550 IntptrTy = Type::getIntNTy(*C, LongSize);
551 PtrTy = PointerType::getUnqual(*C);
552 Int32Ty = Type::getInt32Ty(*C);
553 TargetTriple = M.getTargetTriple();
554
555 Mapping =
556 getShadowMapping(Opts, TargetTriple, LongSize, this->CompileKernel);
557
558 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
559 }
560
561 TypeSize getAllocaSizeInBytes(const AllocaInst &AI) const {
562 return *AI.getAllocationSize(AI.getDataLayout());
563 }
564
565 /// Check if we want (and can) handle this alloca.
566 bool isInterestingAlloca(const AllocaInst &AI);
567
568 bool ignoreAccess(Instruction *Inst, Value *Ptr);
570 Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
571 const TargetTransformInfo *TTI);
572
573 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
574 InterestingMemoryOperand &O, bool UseCalls,
575 const DataLayout &DL, RuntimeCallInserter &RTCI);
576 bool instrumentPointerComparisonOrSubtraction(Instruction *I,
577 RuntimeCallInserter &RTCI);
578 void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
579 Value *Addr, MaybeAlign Alignment,
580 uint32_t TypeStoreSize, bool IsWrite,
581 Value *SizeArgument, bool UseCalls, uint32_t Exp,
582 RuntimeCallInserter &RTCI);
583 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
584 Instruction *InsertBefore, Value *Addr,
585 uint32_t TypeStoreSize, bool IsWrite,
586 Value *SizeArgument);
587 Instruction *genAMDGPUReportBlock(IRBuilder<> &IRB, Value *Cond,
588 bool Recover);
589 void instrumentUnusualSizeOrAlignment(Instruction *I,
590 Instruction *InsertBefore, Value *Addr,
591 TypeSize TypeStoreSize, bool IsWrite,
592 Value *SizeArgument, bool UseCalls,
593 uint32_t Exp,
594 RuntimeCallInserter &RTCI);
595 void instrumentMaskedLoadOrStore(AddressSanitizer *Pass, const DataLayout &DL,
596 Type *IntptrTy, Value *Mask, Value *EVL,
597 Value *Stride, Instruction *I, Value *Addr,
598 MaybeAlign Alignment, unsigned Granularity,
599 Type *OpType, bool IsWrite,
600 Value *SizeArgument, bool UseCalls,
601 uint32_t Exp, RuntimeCallInserter &RTCI);
602 Value *createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong,
603 Value *ShadowValue, uint32_t TypeStoreSize);
604 Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr,
605 bool IsWrite, size_t AccessSizeIndex,
606 Value *SizeArgument, uint32_t Exp,
607 RuntimeCallInserter &RTCI);
608 void instrumentMemIntrinsic(MemIntrinsic *MI, RuntimeCallInserter &RTCI);
609 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
610 bool suppressInstrumentationSiteForDebug(int &Instrumented);
611 bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI,
612 const TargetTransformInfo *TTI);
613 bool maybeInsertAsanInitAtFunctionEntry(Function &F);
614 bool maybeInsertDynamicShadowAtFunctionEntry(Function &F);
615 void markEscapedLocalAllocas(Function &F);
616 void markCatchParametersAsUninteresting(Function &F);
617
618private:
619 friend struct FunctionStackPoisoner;
620
621 void initializeCallbacks(const TargetLibraryInfo *TLI);
622
623 bool LooksLikeCodeInBug11395(Instruction *I);
624 bool GlobalIsLinkerInitialized(GlobalVariable *G);
625 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis, Value *Addr,
626 TypeSize TypeStoreSize) const;
627
628 /// Helper to cleanup per-function state.
629 struct FunctionStateRAII {
630 AddressSanitizer *Pass;
631
632 FunctionStateRAII(AddressSanitizer *Pass) : Pass(Pass) {
633 assert(Pass->ProcessedAllocas.empty() &&
634 "last pass forgot to clear cache");
635 assert(!Pass->LocalDynamicShadow);
636 }
637
638 ~FunctionStateRAII() {
639 Pass->LocalDynamicShadow = nullptr;
640 Pass->ProcessedAllocas.clear();
641 }
642 };
643
644 const InstrumentationOptions &Opts;
645 Module &M;
646 AsanFunctionInserter Inserter;
647 LLVMContext *C;
648 const DataLayout *DL;
649 Triple TargetTriple;
650 int LongSize;
651 bool CompileKernel;
652 bool Recover;
653 bool UseAfterScope;
655 Type *IntptrTy;
656 Type *Int32Ty;
657 PointerType *PtrTy;
658 ShadowMapping Mapping;
659 FunctionCallee AsanHandleNoReturnFunc;
660 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
661 Constant *AsanShadowGlobal;
662
663 // These arrays is indexed by AccessIsWrite, Experiment and log2(AccessSize).
664 FunctionCallee AsanErrorCallback[2][2][kNumberOfAccessSizes];
665 FunctionCallee AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes];
666
667 // These arrays is indexed by AccessIsWrite and Experiment.
668 FunctionCallee AsanErrorCallbackSized[2][2];
669 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
670
671 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
672 Value *LocalDynamicShadow = nullptr;
673 const StackSafetyGlobalInfo *SSGI;
674 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
675
676 FunctionCallee AMDGPUAddressShared;
677 FunctionCallee AMDGPUAddressPrivate;
678 int InstrumentationWithCallsThreshold;
679 uint32_t MaxInlinePoisoningSize;
680};
681
682class ModuleAddressSanitizer {
683public:
684 ModuleAddressSanitizer(const InstrumentationOptions &Opts, Module &M,
685 bool InsertVersionCheck, bool CompileKernel = false,
686 bool Recover = false, bool UseGlobalsGC = true,
687 bool UseOdrIndicator = true,
688 AsanDtorKind DestructorKind = AsanDtorKind::Global,
689 AsanCtorKind ConstructorKind = AsanCtorKind::Global)
690 : Opts(Opts), M(M), Inserter(M),
691 CompileKernel(valueOr(Opts.asan_kernel, CompileKernel)),
692 InsertVersionCheck(valueOr(Opts.asan_guard_against_version_mismatch,
693 InsertVersionCheck)),
694 Recover(valueOr(Opts.asan_recover, Recover)),
695 UseGlobalsGC(UseGlobalsGC && Opts.asan_globals_live_support &&
696 !this->CompileKernel),
697 // Enable aliases as they should have no downside with ODR indicators.
698 UsePrivateAlias(valueOr(Opts.asan_use_private_alias, UseOdrIndicator)),
699 UseOdrIndicator(valueOr(Opts.asan_use_odr_indicator, UseOdrIndicator)),
700 // Not a typo: -asan-with-comdat is almost completely pointless without
701 // -asan-globals-live-support (because then it only works on modules
702 // without globals, which are rare); it is a prerequisite for
703 // -asan-globals-live-support; and both suffer from gold PR19002 for
704 // which UseGlobalsGC constructor argument is designed as workaround.
705 // Therefore, disable both -asan-with-comdat and
706 // -asan-globals-live-support unless the frontend says it's ok to do
707 // globals-gc.
708 UseCtorComdat(UseGlobalsGC && Opts.asan_with_comdat &&
709 !this->CompileKernel),
710 DestructorKind(Opts.asan_destructor_kind.value_or(DestructorKind)),
711 ConstructorKind(Opts.asan_constructor_kind.value_or(ConstructorKind)) {
712 C = &(M.getContext());
713 int LongSize = M.getDataLayout().getPointerSizeInBits();
714 IntptrTy = Type::getIntNTy(*C, LongSize);
715 PtrTy = PointerType::getUnqual(*C);
716 TargetTriple = M.getTargetTriple();
717 Mapping =
718 getShadowMapping(Opts, TargetTriple, LongSize, this->CompileKernel);
719
720 assert(this->DestructorKind != AsanDtorKind::Invalid);
721 }
722
723 bool instrumentModule();
724
725private:
726 void initializeCallbacks();
727
728 void instrumentGlobals(IRBuilder<> &IRB, bool *CtorComdat);
729 void InstrumentGlobalsCOFF(IRBuilder<> &IRB,
730 ArrayRef<GlobalVariable *> ExtendedGlobals,
731 ArrayRef<Constant *> MetadataInitializers);
732 void instrumentGlobalsELF(IRBuilder<> &IRB,
733 ArrayRef<GlobalVariable *> ExtendedGlobals,
734 ArrayRef<Constant *> MetadataInitializers,
735 const std::string &UniqueModuleId);
736 void InstrumentGlobalsMachO(IRBuilder<> &IRB,
737 ArrayRef<GlobalVariable *> ExtendedGlobals,
738 ArrayRef<Constant *> MetadataInitializers);
739 void
740 InstrumentGlobalsWithMetadataArray(IRBuilder<> &IRB,
741 ArrayRef<GlobalVariable *> ExtendedGlobals,
742 ArrayRef<Constant *> MetadataInitializers);
743
744 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
745 StringRef OriginalName);
746 void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata,
747 StringRef InternalSuffix);
748 Instruction *CreateAsanModuleDtor();
749
750 const GlobalVariable *getExcludedAliasedGlobal(const GlobalAlias &GA) const;
751 bool shouldInstrumentGlobal(GlobalVariable *G) const;
752 bool ShouldUseMachOGlobalsSection() const;
753 StringRef getGlobalMetadataSection() const;
754 void poisonOneInitializer(Function &GlobalInit);
755 void createInitializerPoisonCalls();
756 uint64_t getMinRedzoneSizeForGlobal() const {
757 return getRedzoneSizeForScale(Mapping.Scale);
758 }
759 uint64_t getRedzoneSizeForGlobal(uint64_t SizeInBytes) const;
760 int GetAsanVersion() const;
761 GlobalVariable *getOrCreateModuleName();
762
763 const InstrumentationOptions &Opts;
764 Module &M;
765 AsanFunctionInserter Inserter;
766 bool CompileKernel;
767 bool InsertVersionCheck;
768 bool Recover;
769 bool UseGlobalsGC;
770 bool UsePrivateAlias;
771 bool UseOdrIndicator;
772 bool UseCtorComdat;
773 AsanDtorKind DestructorKind;
774 AsanCtorKind ConstructorKind;
775 Type *IntptrTy;
776 PointerType *PtrTy;
777 LLVMContext *C;
778 Triple TargetTriple;
779 ShadowMapping Mapping;
780 FunctionCallee AsanPoisonGlobals;
781 FunctionCallee AsanUnpoisonGlobals;
782 FunctionCallee AsanRegisterGlobals;
783 FunctionCallee AsanUnregisterGlobals;
784 FunctionCallee AsanRegisterImageGlobals;
785 FunctionCallee AsanUnregisterImageGlobals;
786 FunctionCallee AsanRegisterElfGlobals;
787 FunctionCallee AsanUnregisterElfGlobals;
788
789 Function *AsanCtorFunction = nullptr;
790 Function *AsanDtorFunction = nullptr;
791 GlobalVariable *ModuleName = nullptr;
792};
793
794// Stack poisoning does not play well with exception handling.
795// When an exception is thrown, we essentially bypass the code
796// that unpoisones the stack. This is why the run-time library has
797// to intercept __cxa_throw (as well as longjmp, etc) and unpoison the entire
798// stack in the interceptor. This however does not work inside the
799// actual function which catches the exception. Most likely because the
800// compiler hoists the load of the shadow value somewhere too high.
801// This causes asan to report a non-existing bug on 453.povray.
802// It sounds like an LLVM bug.
803struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
804 const InstrumentationOptions &Opts;
805 Function &F;
806 AddressSanitizer &ASan;
807 RuntimeCallInserter &RTCI;
808 DIBuilder DIB;
809 LLVMContext *C;
810 Type *IntptrTy;
811 Type *IntptrPtrTy;
812 ShadowMapping Mapping;
813
815 SmallVector<AllocaInst *, 16> StaticAllocasToMoveUp;
816 SmallVector<Instruction *, 8> RetVec;
817
818 FunctionCallee AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1],
819 AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1];
820 FunctionCallee AsanSetShadowFunc[0x100] = {};
821 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
822 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
823
824 // Stores a place and arguments of poisoning/unpoisoning call for alloca.
825 struct AllocaPoisonCall {
826 IntrinsicInst *InsBefore;
827 AllocaInst *AI;
829 bool DoPoison;
830 };
831 SmallVector<AllocaPoisonCall, 8> DynamicAllocaPoisonCallVec;
832 SmallVector<AllocaPoisonCall, 8> StaticAllocaPoisonCallVec;
833
834 SmallVector<AllocaInst *, 1> DynamicAllocaVec;
835 SmallVector<IntrinsicInst *, 1> StackRestoreVec;
836 AllocaInst *DynamicAllocaLayout = nullptr;
837 IntrinsicInst *LocalEscapeCall = nullptr;
838
839 bool HasInlineAsm = false;
840 bool HasReturnsTwiceCall = false;
841 bool PoisonStack;
842
843 FunctionStackPoisoner(Function &F, AddressSanitizer &ASan,
844 RuntimeCallInserter &RTCI)
845 : Opts(ASan.Opts), F(F), ASan(ASan), RTCI(RTCI),
846 DIB(*F.getParent(), /*AllowUnresolved*/ false), C(ASan.C),
847 IntptrTy(ASan.IntptrTy),
848 IntptrPtrTy(PointerType::get(IntptrTy->getContext(), 0)),
849 Mapping(ASan.Mapping),
850 PoisonStack(Opts.asan_stack &&
851 !F.getParent()->getTargetTriple().isAMDGPU()) {}
852
853 bool runOnFunction() {
854 if (!PoisonStack)
855 return false;
856
857 if (Opts.asan_redzone_byval_args)
858 copyArgsPassedByValToAllocas();
859
860 // Collect alloca, ret, lifetime instructions etc.
861 for (BasicBlock *BB : depth_first(&F.getEntryBlock())) visit(*BB);
862
863 if (AllocaVec.empty() && DynamicAllocaVec.empty()) return false;
864
865 initializeCallbacks(*F.getParent());
866
867 processDynamicAllocas();
868 processStaticAllocas();
869
870 if (Opts.asan_debug_stack) {
871 LLVM_DEBUG(dbgs() << F);
872 }
873 return true;
874 }
875
876 // Arguments marked with the "byval" attribute are implicitly copied without
877 // using an alloca instruction. To produce redzones for those arguments, we
878 // copy them a second time into memory allocated with an alloca instruction.
879 void copyArgsPassedByValToAllocas();
880
881 // Finds all Alloca instructions and puts
882 // poisoned red zones around all of them.
883 // Then unpoison everything back before the function returns.
884 void processStaticAllocas();
885 void processDynamicAllocas();
886
887 void createDynamicAllocasInitStorage();
888
889 // ----------------------- Visitors.
890 /// Collect all Ret instructions, or the musttail call instruction if it
891 /// precedes the return instruction.
892 void visitReturnInst(ReturnInst &RI) {
893 if (CallInst *CI = RI.getParent()->getTerminatingMustTailCall())
894 RetVec.push_back(CI);
895 else
896 RetVec.push_back(&RI);
897 }
898
899 /// Collect all Resume instructions.
900 void visitResumeInst(ResumeInst &RI) { RetVec.push_back(&RI); }
901
902 /// Collect all CatchReturnInst instructions.
903 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.push_back(&CRI); }
904
905 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
906 Value *SavedStack) {
907 IRBuilder<> IRB(InstBefore);
908 Value *DynamicAreaPtr = IRB.CreatePtrToInt(SavedStack, IntptrTy);
909 // When we insert _asan_allocas_unpoison before @llvm.stackrestore, we
910 // need to adjust extracted SP to compute the address of the most recent
911 // alloca. We have a special @llvm.get.dynamic.area.offset intrinsic for
912 // this purpose.
913 if (!isa<ReturnInst>(InstBefore)) {
914 Value *DynamicAreaOffset = IRB.CreateIntrinsic(
915 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
916
917 DynamicAreaPtr = IRB.CreateAdd(IRB.CreatePtrToInt(SavedStack, IntptrTy),
918 DynamicAreaOffset);
919 }
920
921 RTCI.createRuntimeCall(
922 IRB, AsanAllocasUnpoisonFunc,
923 {IRB.CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
924 }
925
926 // Unpoison dynamic allocas redzones.
927 void unpoisonDynamicAllocas() {
928 for (Instruction *Ret : RetVec)
929 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
930
931 for (Instruction *StackRestoreInst : StackRestoreVec)
932 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
933 StackRestoreInst->getOperand(0));
934 }
935
936 // Deploy and poison redzones around dynamic alloca call. To do this, we
937 // should replace this call with another one with changed parameters and
938 // replace all its uses with new address, so
939 // addr = alloca type, old_size, align
940 // is replaced by
941 // new_size = (old_size + additional_size) * sizeof(type)
942 // tmp = alloca i8, new_size, max(align, 32)
943 // addr = tmp + 32 (first 32 bytes are for the left redzone).
944 // Additional_size is added to make new memory allocation contain not only
945 // requested memory, but also left, partial and right redzones.
946 void handleDynamicAllocaCall(AllocaInst *AI);
947
948 /// Collect Alloca instructions we want (and can) handle.
949 void visitAllocaInst(AllocaInst &AI) {
950 // FIXME: Handle scalable vectors instead of ignoring them.
951 if (!ASan.isInterestingAlloca(AI) || AI.isScalable()) {
952 if (AI.isStaticAlloca()) {
953 // Skip over allocas that are present *before* the first instrumented
954 // alloca, we don't want to move those around.
955 if (AllocaVec.empty())
956 return;
957
958 StaticAllocasToMoveUp.push_back(&AI);
959 }
960 return;
961 }
962
963 if (!AI.isStaticAlloca())
964 DynamicAllocaVec.push_back(&AI);
965 else
966 AllocaVec.push_back(&AI);
967 }
968
969 /// Collect lifetime intrinsic calls to check for use-after-scope
970 /// errors.
971 void visitIntrinsicInst(IntrinsicInst &II) {
972 Intrinsic::ID ID = II.getIntrinsicID();
973 if (ID == Intrinsic::stackrestore) StackRestoreVec.push_back(&II);
974 if (ID == Intrinsic::localescape) LocalEscapeCall = &II;
975 if (!ASan.UseAfterScope)
976 return;
977 if (!II.isLifetimeStartOrEnd())
978 return;
979 // Find alloca instruction that corresponds to llvm.lifetime argument.
980 AllocaInst *AI = dyn_cast<AllocaInst>(II.getArgOperand(0));
981 // We're interested only in allocas we can handle.
982 if (!AI || !ASan.isInterestingAlloca(*AI))
983 return;
984
985 std::optional<TypeSize> Size = AI->getAllocationSize(AI->getDataLayout());
986 // Check that size is known and can be stored in IntptrTy.
987 // TODO: Add support for scalable vectors if possible.
988 if (!Size || Size->isScalable() ||
990 return;
991
992 bool DoPoison = (ID == Intrinsic::lifetime_end);
993 AllocaPoisonCall APC = {&II, AI, *Size, DoPoison};
994 if (AI->isStaticAlloca())
995 StaticAllocaPoisonCallVec.push_back(APC);
996 else if (Opts.asan_instrument_dynamic_allocas)
997 DynamicAllocaPoisonCallVec.push_back(APC);
998 }
999
1000 void visitCallBase(CallBase &CB) {
1001 if (CallInst *CI = dyn_cast<CallInst>(&CB)) {
1002 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1003 HasReturnsTwiceCall |= CI->canReturnTwice();
1004 }
1005 }
1006
1007 // ---------------------- Helpers.
1008 void initializeCallbacks(Module &M);
1009
1010 // Copies bytes from ShadowBytes into shadow memory for indexes where
1011 // ShadowMask is not zero. If ShadowMask[i] is zero, we assume that
1012 // ShadowBytes[i] is constantly zero and doesn't need to be overwritten.
1013 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1014 IRBuilder<> &IRB, Value *ShadowBase);
1015 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1016 size_t Begin, size_t End, IRBuilder<> &IRB,
1017 Value *ShadowBase);
1018 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1019 ArrayRef<uint8_t> ShadowBytes, size_t Begin,
1020 size_t End, IRBuilder<> &IRB, Value *ShadowBase);
1021
1022 void poisonAlloca(Value *V, uint64_t Size, IRBuilder<> &IRB, bool DoPoison);
1023
1024 Value *createAllocaForLayout(IRBuilder<> &IRB, const ASanStackFrameLayout &L,
1025 bool Dynamic);
1026 PHINode *createPHI(IRBuilder<> &IRB, Value *Cond, Value *ValueIfTrue,
1027 Instruction *ThenTerm, Value *ValueIfFalse);
1028};
1029
1030} // end anonymous namespace
1031
1033 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
1034 static_cast<PassInfoMixin<AddressSanitizerPass> *>(this)->printPipeline(
1035 OS, MapClassName2PassName);
1036 OS << '<';
1037 if (Options.CompileKernel)
1038 OS << "kernel;";
1039 if (Options.UseAfterScope)
1040 OS << "use-after-scope";
1041 OS << '>';
1042}
1043
1045 const AddressSanitizerOptions &Options, bool UseGlobalGC,
1046 bool UseOdrIndicator, AsanDtorKind DestructorKind,
1047 AsanCtorKind ConstructorKind)
1048 : Options(Options), UseGlobalGC(UseGlobalGC),
1049 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1050 ConstructorKind(ConstructorKind) {}
1051
1054 // Return early if nosanitize_address module flag is present for the module.
1055 // This implies that asan pass has already run before.
1056 if (checkIfAlreadyInstrumented(M, "nosanitize_address"))
1057 return PreservedAnalyses::all();
1058
1059 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
1060 ModuleAddressSanitizer ModuleSanitizer(Opts, M, Options.InsertVersionCheck,
1061 Options.CompileKernel, Options.Recover,
1062 UseGlobalGC, UseOdrIndicator,
1063 DestructorKind, ConstructorKind);
1064 bool Modified = false;
1065 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1066 const StackSafetyGlobalInfo *const SSGI =
1067 Opts.asan_use_stack_safety ? &MAM.getResult<StackSafetyGlobalAnalysis>(M)
1068 : nullptr;
1069 for (Function &F : M) {
1070 if (F.empty())
1071 continue;
1072 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
1073 continue;
1074 if (!Opts.asan_debug_func.empty() && Opts.asan_debug_func == F.getName())
1075 continue;
1076 if (F.getName().starts_with("__asan_"))
1077 continue;
1078 if (F.isPresplitCoroutine())
1079 continue;
1080 AddressSanitizer FunctionSanitizer(
1081 Opts, M, SSGI, Options.InstrumentationWithCallsThreshold,
1082 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1083 Options.UseAfterScope, Options.UseAfterReturn);
1084 const TargetLibraryInfo &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
1085 const TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
1086 Modified |= FunctionSanitizer.instrumentFunction(F, &TLI, &TTI);
1087 }
1088 Modified |= ModuleSanitizer.instrumentModule();
1089 if (!Modified)
1090 return PreservedAnalyses::all();
1091
1093 // GlobalsAA is considered stateless and does not get invalidated unless
1094 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
1095 // make changes that require GlobalsAA to be invalidated.
1096 PA.abandon<GlobalsAA>();
1097 return PA;
1098}
1099
1101 size_t Res = llvm::countr_zero(TypeSize / 8);
1103 return Res;
1104}
1105
1106/// Check if \p G has been created by a trusted compiler pass.
1108 // Do not instrument @llvm.global_ctors, @llvm.used, etc.
1109 if (G->getName().starts_with("llvm.") ||
1110 // Do not instrument gcov counter arrays.
1111 G->getName().starts_with("__llvm_gcov_ctr") ||
1112 // Do not instrument rtti proxy symbols for function sanitizer.
1113 G->getName().starts_with("__llvm_rtti_proxy"))
1114 return true;
1115
1116 // Do not instrument asan globals.
1117 if (G->getName().starts_with(kAsanGenPrefix) ||
1118 G->getName().starts_with(kSanCovGenPrefix) ||
1119 G->getName().starts_with(kODRGenPrefix))
1120 return true;
1121
1122 return false;
1123}
1124
1126 Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
1127 unsigned int AddrSpace = PtrTy->getPointerAddressSpace();
1128 // Globals in address space 1 and 4 are supported for AMDGPU.
1129 if (AddrSpace == 3 || AddrSpace == 5)
1130 return true;
1131 return false;
1132}
1133
1134static bool isSupportedAddrspace(const InstrumentationOptions &Opts,
1135 const Triple &TargetTriple, Value *Addr) {
1136 Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
1137 unsigned int AddrSpace = PtrTy->getPointerAddressSpace();
1138
1139 if (!Opts.asan_instrument_address_spaces.empty())
1140 return is_contained(Opts.asan_instrument_address_spaces, AddrSpace);
1141
1142 if (TargetTriple.isAMDGPU())
1143 return !isUnsupportedAMDGPUAddrspace(Addr);
1144
1145 return AddrSpace == 0;
1146}
1147
1148Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
1149 if (TargetTriple.isOSDarwin() &&
1150 TargetTriple.getArch() == llvm::Triple::aarch64) {
1151 // Strip MTE-tag bits before translating to shadow address
1152 Shadow = IRB.CreateAnd(Shadow,
1153 ConstantInt::get(IntptrTy, ~(uint64_t(0x0f) << 56)));
1154 }
1155 // Shadow >> scale
1156 Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
1157 if (Mapping.Offset == 0) return Shadow;
1158 // (Shadow >> scale) | offset
1159 Value *ShadowBase;
1160 if (LocalDynamicShadow)
1161 ShadowBase = LocalDynamicShadow;
1162 else
1163 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1164 if (Mapping.OrShadowOffset)
1165 return IRB.CreateOr(Shadow, ShadowBase);
1166 else
1167 return IRB.CreateAdd(Shadow, ShadowBase);
1168}
1169
1170// Instrument memset/memmove/memcpy
1171void AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI,
1172 RuntimeCallInserter &RTCI) {
1174 if (isa<MemTransferInst>(MI)) {
1175 RTCI.createRuntimeCall(
1176 IRB, isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
1177 {IRB.CreateAddrSpaceCast(MI->getOperand(0), PtrTy),
1178 IRB.CreateAddrSpaceCast(MI->getOperand(1), PtrTy),
1179 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
1180 } else if (isa<MemSetInst>(MI)) {
1181 RTCI.createRuntimeCall(
1182 IRB, AsanMemset,
1183 {IRB.CreateAddrSpaceCast(MI->getOperand(0), PtrTy),
1184 IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
1185 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
1186 }
1187 MI->eraseFromParent();
1188}
1189
1190/// Check if we want (and can) handle this alloca.
1191bool AddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
1192 auto [It, Inserted] = ProcessedAllocas.try_emplace(&AI);
1193
1194 if (!Inserted)
1195 return It->getSecond();
1196
1197 bool IsInteresting = // alloca() may be called with 0 size, ignore it.
1198 (((!AI.isStaticAlloca()) || !getAllocaSizeInBytes(AI).isZero()) &&
1199 // We are only interested in allocas not promotable to registers.
1200 // Promotable allocas are common under -O0.
1201 (!Opts.asan_skip_promotable_allocas || !isAllocaPromotable(&AI)) &&
1202 // inalloca allocas are not treated as static, and we don't want
1203 // dynamic alloca instrumentation for them as well.
1204 !AI.isUsedWithInAlloca() &&
1205 // swifterror allocas are register promoted by ISel
1206 !AI.isSwiftError() &&
1207 // safe allocas are not interesting
1208 !(SSGI && SSGI->isSafe(AI)));
1209
1210 It->second = IsInteresting;
1211 return IsInteresting;
1212}
1213
1214bool AddressSanitizer::ignoreAccess(Instruction *Inst, Value *Ptr) {
1215 // Check whether the target supports sanitizing the address space
1216 // of the pointer.
1217 if (!isSupportedAddrspace(Opts, TargetTriple, Ptr))
1218 return true;
1219
1220 // Ignore swifterror addresses.
1221 // swifterror memory addresses are mem2reg promoted by instruction
1222 // selection. As such they cannot have regular uses like an instrumentation
1223 // function and it makes no sense to track them as memory.
1224 if (Ptr->isSwiftError())
1225 return true;
1226
1227 // Treat memory accesses to promotable allocas as non-interesting since they
1228 // will not cause memory violations. This greatly speeds up the instrumented
1229 // executable at -O0.
1230 if (auto AI = dyn_cast_or_null<AllocaInst>(Ptr))
1231 if (Opts.asan_skip_promotable_allocas && !isInterestingAlloca(*AI))
1232 return true;
1233
1234 if (SSGI != nullptr && SSGI->stackAccessIsSafe(*Inst) &&
1235 findAllocaForValue(Ptr))
1236 return true;
1237
1238 return false;
1239}
1240
1241void AddressSanitizer::getInterestingMemoryOperands(
1243 const TargetTransformInfo *TTI) {
1244 // Do not instrument the load fetching the dynamic shadow address.
1245 if (LocalDynamicShadow == I)
1246 return;
1247
1248 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
1249 if (!Opts.asan_instrument_reads || ignoreAccess(I, LI->getPointerOperand()))
1250 return;
1251 Interesting.emplace_back(I, LI->getPointerOperandIndex(), false,
1252 LI->getType(), LI->getAlign());
1253 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
1254 if (!Opts.asan_instrument_writes ||
1255 ignoreAccess(I, SI->getPointerOperand()))
1256 return;
1257 Interesting.emplace_back(I, SI->getPointerOperandIndex(), true,
1258 SI->getValueOperand()->getType(), SI->getAlign());
1259 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
1260 if (!Opts.asan_instrument_atomics ||
1261 ignoreAccess(I, RMW->getPointerOperand()))
1262 return;
1263 Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true,
1264 RMW->getValOperand()->getType(), std::nullopt);
1265 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
1266 if (!Opts.asan_instrument_atomics ||
1267 ignoreAccess(I, XCHG->getPointerOperand()))
1268 return;
1269 Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
1270 XCHG->getCompareOperand()->getType(),
1271 std::nullopt);
1272 } else if (auto CI = dyn_cast<CallInst>(I)) {
1273 switch (CI->getIntrinsicID()) {
1274 case Intrinsic::masked_load:
1275 case Intrinsic::masked_store:
1276 case Intrinsic::masked_gather:
1277 case Intrinsic::masked_scatter: {
1278 bool IsWrite = CI->getType()->isVoidTy();
1279 // Masked store has an initial operand for the value.
1280 unsigned OpOffset = IsWrite ? 1 : 0;
1281 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1282 return;
1283
1284 auto BasePtr = CI->getOperand(OpOffset);
1285 if (ignoreAccess(I, BasePtr))
1286 return;
1287 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1288 MaybeAlign Alignment = CI->getParamAlign(0);
1289 Value *Mask = CI->getOperand(1 + OpOffset);
1290 Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, Mask);
1291 break;
1292 }
1293 case Intrinsic::masked_expandload:
1294 case Intrinsic::masked_compressstore: {
1295 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1296 unsigned OpOffset = IsWrite ? 1 : 0;
1297 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1298 return;
1299 auto BasePtr = CI->getOperand(OpOffset);
1300 if (ignoreAccess(I, BasePtr))
1301 return;
1302 MaybeAlign Alignment = BasePtr->getPointerAlignment(*DL);
1303 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1304
1305 IRBuilder IB(I);
1306 Value *Mask = CI->getOperand(1 + OpOffset);
1307 // Use the popcount of Mask as the effective vector length.
1308 Type *ExtTy = VectorType::get(IntptrTy, cast<VectorType>(Ty));
1309 Value *ExtMask = IB.CreateZExt(Mask, ExtTy);
1310 Value *EVL = IB.CreateAddReduce(ExtMask);
1311 Value *TrueMask = ConstantInt::get(Mask->getType(), 1);
1312 Interesting.emplace_back(I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1313 EVL);
1314 break;
1315 }
1316 case Intrinsic::vp_load:
1317 case Intrinsic::vp_store:
1318 case Intrinsic::experimental_vp_strided_load:
1319 case Intrinsic::experimental_vp_strided_store: {
1320 auto *VPI = cast<VPIntrinsic>(CI);
1321 unsigned IID = CI->getIntrinsicID();
1322 bool IsWrite = CI->getType()->isVoidTy();
1323 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1324 return;
1325 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1326 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1327 MaybeAlign Alignment = VPI->getOperand(PtrOpNo)->getPointerAlignment(*DL);
1328 Value *Stride = nullptr;
1329 if (IID == Intrinsic::experimental_vp_strided_store ||
1330 IID == Intrinsic::experimental_vp_strided_load) {
1331 Stride = VPI->getOperand(PtrOpNo + 1);
1332 // Use the pointer alignment as the element alignment if the stride is a
1333 // multiple of the pointer alignment. Otherwise, the element alignment
1334 // should be Align(1).
1335 unsigned PointerAlign = Alignment.valueOrOne().value();
1336 if (!isa<ConstantInt>(Stride) ||
1337 cast<ConstantInt>(Stride)->getZExtValue() % PointerAlign != 0)
1338 Alignment = Align(1);
1339 }
1340 Interesting.emplace_back(I, PtrOpNo, IsWrite, Ty, Alignment,
1341 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1342 Stride);
1343 break;
1344 }
1345 case Intrinsic::vp_gather:
1346 case Intrinsic::vp_scatter: {
1347 auto *VPI = cast<VPIntrinsic>(CI);
1348 unsigned IID = CI->getIntrinsicID();
1349 bool IsWrite = IID == Intrinsic::vp_scatter;
1350 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1351 return;
1352 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1353 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1354 MaybeAlign Alignment = VPI->getPointerAlignment();
1355 Interesting.emplace_back(I, PtrOpNo, IsWrite, Ty, Alignment,
1356 VPI->getMaskParam(),
1357 VPI->getVectorLengthParam());
1358 break;
1359 }
1360 default:
1361 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1362 MemIntrinsicInfo IntrInfo;
1363 if (TTI->getTgtMemIntrinsic(II, IntrInfo))
1364 Interesting = IntrInfo.InterestingOperands;
1365 return;
1366 }
1367 for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1368 if (!Opts.asan_instrument_byval || !CI->isByValArgument(ArgNo) ||
1369 ignoreAccess(I, CI->getArgOperand(ArgNo)))
1370 continue;
1371 Type *Ty = CI->getParamByValType(ArgNo);
1372 Interesting.emplace_back(I, ArgNo, false, Ty, Align(1));
1373 }
1374 }
1375 }
1376}
1377
1378static bool isPointerOperand(Value *V) {
1379 return V->getType()->isPointerTy() || isa<PtrToIntInst, PtrToAddrInst>(V);
1380}
1381
1382// This is a rough heuristic; it may cause both false positives and
1383// false negatives. The proper implementation requires cooperation with
1384// the frontend.
1386 if (ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) {
1387 if (!Cmp->isRelational())
1388 return false;
1389 } else {
1390 return false;
1391 }
1392 return isPointerOperand(I->getOperand(0)) &&
1393 isPointerOperand(I->getOperand(1));
1394}
1395
1396// This is a rough heuristic; it may cause both false positives and
1397// false negatives. The proper implementation requires cooperation with
1398// the frontend.
1401 if (BO->getOpcode() != Instruction::Sub)
1402 return false;
1403 } else {
1404 return false;
1405 }
1406 return isPointerOperand(I->getOperand(0)) &&
1407 isPointerOperand(I->getOperand(1));
1408}
1409
1410bool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) {
1411 // If a global variable does not have dynamic initialization we don't
1412 // have to instrument it. However, if a global does not have initializer
1413 // at all, we assume it has dynamic initializer (in other TU).
1414 if (!G->hasInitializer())
1415 return false;
1416
1417 if (G->hasSanitizerMetadata() && G->getSanitizerMetadata().IsDynInit)
1418 return false;
1419
1420 return true;
1421}
1422
1423static bool isPointerPairOperand(Value *V, Type *IntptrTy) {
1424 Type *Ty = V->getType();
1425 if (Ty->isPtrOrPtrVectorTy())
1426 return true;
1427 return Ty->isIntOrIntVectorTy() &&
1428 Ty->getScalarSizeInBits() == IntptrTy->getScalarSizeInBits();
1429}
1430
1431bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1432 Instruction *I, RuntimeCallInserter &RTCI) {
1433 Value *Param[2] = {I->getOperand(0), I->getOperand(1)};
1434 if (!isPointerPairOperand(Param[0], IntptrTy) ||
1435 !isPointerPairOperand(Param[1], IntptrTy))
1436 return false;
1437
1438 IRBuilder<> IRB(I);
1439 FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
1440
1441 if (const auto *Ty = Param[0]->getType(); Ty->isVectorTy()) {
1442 const auto *VTy = dyn_cast<FixedVectorType>(Ty);
1443 // TODO: Add support for scalable vectors if possible.
1444 if (!VTy)
1445 return false;
1446
1447 assert(Param[0]->getType() == Param[1]->getType() &&
1448 "invalid vector pointer pair instrumentation operands");
1449 for (unsigned Index = 0, NumElements = VTy->getNumElements();
1450 Index != NumElements; ++Index) {
1451 Value *ScalarParam[2] = {
1453 IRB.CreateExtractElement(Param[0], IRB.getInt32(Index)),
1454 IntptrTy),
1456 IRB.CreateExtractElement(Param[1], IRB.getInt32(Index)),
1457 IntptrTy)};
1458 RTCI.createRuntimeCall(IRB, F, ScalarParam);
1459 }
1460 return true;
1461 }
1462
1463 for (Value *&P : Param)
1464 P = IRB.CreatePointerCast(P, IntptrTy);
1465 RTCI.createRuntimeCall(IRB, F, Param);
1466 return true;
1467}
1468
1469static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
1470 Instruction *InsertBefore, Value *Addr,
1471 MaybeAlign Alignment, unsigned Granularity,
1472 TypeSize TypeStoreSize, bool IsWrite,
1473 Value *SizeArgument, bool UseCalls,
1474 uint32_t Exp, RuntimeCallInserter &RTCI) {
1475 // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
1476 // if the data is properly aligned.
1477 if (!TypeStoreSize.isScalable()) {
1478 const auto FixedSize = TypeStoreSize.getFixedValue();
1479 switch (FixedSize) {
1480 case 8:
1481 case 16:
1482 case 32:
1483 case 64:
1484 case 128:
1485 if (!Alignment || *Alignment >= Granularity ||
1486 *Alignment >= FixedSize / 8)
1487 return Pass->instrumentAddress(I, InsertBefore, Addr, Alignment,
1488 FixedSize, IsWrite, nullptr, UseCalls,
1489 Exp, RTCI);
1490 }
1491 }
1492 Pass->instrumentUnusualSizeOrAlignment(I, InsertBefore, Addr, TypeStoreSize,
1493 IsWrite, nullptr, UseCalls, Exp, RTCI);
1494}
1495
1496void AddressSanitizer::instrumentMaskedLoadOrStore(
1497 AddressSanitizer *Pass, const DataLayout &DL, Type *IntptrTy, Value *Mask,
1498 Value *EVL, Value *Stride, Instruction *I, Value *Addr,
1499 MaybeAlign Alignment, unsigned Granularity, Type *OpType, bool IsWrite,
1500 Value *SizeArgument, bool UseCalls, uint32_t Exp,
1501 RuntimeCallInserter &RTCI) {
1502 auto *VTy = cast<VectorType>(OpType);
1503 TypeSize ElemTypeSize = DL.getTypeStoreSizeInBits(VTy->getScalarType());
1504 auto Zero = ConstantInt::get(IntptrTy, 0);
1505
1506 IRBuilder IB(I);
1507 Instruction *LoopInsertBefore = I;
1508 if (EVL) {
1509 // The end argument of SplitBlockAndInsertForLane is assumed bigger
1510 // than zero, so we should check whether EVL is zero here.
1511 Type *EVLType = EVL->getType();
1512 Value *IsEVLZero = IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1513 LoopInsertBefore = SplitBlockAndInsertIfThen(IsEVLZero, I, false);
1514 IB.SetInsertPoint(LoopInsertBefore);
1515 // Cast EVL to IntptrTy.
1516 EVL = IB.CreateZExtOrTrunc(EVL, IntptrTy);
1517 // To avoid undefined behavior for extracting with out of range index, use
1518 // the minimum of evl and element count as trip count.
1519 Value *EC = IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1520 EVL = IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1521 } else {
1522 EVL = IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1523 }
1524
1525 // Cast Stride to IntptrTy.
1526 if (Stride)
1527 Stride = IB.CreateZExtOrTrunc(Stride, IntptrTy);
1528
1529 SplitBlockAndInsertForEachLane(EVL, LoopInsertBefore->getIterator(),
1530 [&](IRBuilderBase &IRB, Value *Index) {
1531 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1532 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1533 if (MaskElemC->isZero())
1534 // No check
1535 return;
1536 // Unconditional check
1537 } else {
1538 // Conditional check
1539 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1540 MaskElem, &*IRB.GetInsertPoint(), false);
1541 IRB.SetInsertPoint(ThenTerm);
1542 }
1543
1544 Value *InstrumentedAddress;
1545 if (isa<VectorType>(Addr->getType())) {
1546 assert(
1547 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1548 "Expected vector of pointer.");
1549 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1550 } else if (Stride) {
1551 Index = IRB.CreateMul(Index, Stride);
1552 InstrumentedAddress = IRB.CreatePtrAdd(Addr, Index);
1553 } else {
1554 InstrumentedAddress = IRB.CreateGEP(VTy, Addr, {Zero, Index});
1555 }
1556 doInstrumentAddress(Pass, I, &*IRB.GetInsertPoint(), InstrumentedAddress,
1557 Alignment, Granularity, ElemTypeSize, IsWrite,
1558 SizeArgument, UseCalls, Exp, RTCI);
1559 });
1560}
1561
1562void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
1563 InterestingMemoryOperand &O, bool UseCalls,
1564 const DataLayout &DL,
1565 RuntimeCallInserter &RTCI) {
1566 Value *Addr = O.getPtr();
1567
1568 // Optimization experiments.
1569 // The experiments can be used to evaluate potential optimizations that remove
1570 // instrumentation (assess false negatives). Instead of completely removing
1571 // some instrumentation, you set Exp to a non-zero value (mask of optimization
1572 // experiments that want to remove instrumentation of this instruction).
1573 // If Exp is non-zero, this pass will emit special calls into runtime
1574 // (e.g. __asan_report_exp_load1 instead of __asan_report_load1). These calls
1575 // make runtime terminate the program in a special way (with a different
1576 // exit status). Then you run the new compiler on a buggy corpus, collect
1577 // the special terminations (ideally, you don't see them at all -- no false
1578 // negatives) and make the decision on the optimization.
1579 uint32_t Exp = Opts.asan_force_experiment;
1580
1581 if (Opts.asan_opt && Opts.asan_opt_globals) {
1582 // If initialization order checking is disabled, a simple access to a
1583 // dynamically initialized global is always valid.
1585 if (G &&
1586 (!Opts.asan_initialization_order || GlobalIsLinkerInitialized(G)) &&
1587 isSafeAccess(ObjSizeVis, Addr, O.TypeStoreSize)) {
1588 NumOptimizedAccessesToGlobalVar++;
1589 return;
1590 }
1591 }
1592
1593 if (Opts.asan_opt && Opts.asan_opt_stack) {
1594 // A direct inbounds access to a stack variable is always valid.
1596 isSafeAccess(ObjSizeVis, Addr, O.TypeStoreSize)) {
1597 NumOptimizedAccessesToStackVar++;
1598 return;
1599 }
1600 }
1601
1602 if (O.IsWrite)
1603 NumInstrumentedWrites++;
1604 else
1605 NumInstrumentedReads++;
1606
1607 if (O.MaybeByteOffset) {
1608 Type *Ty = Type::getInt8Ty(*C);
1609 IRBuilder IB(O.getInsn());
1610
1611 Value *OffsetOp = O.MaybeByteOffset;
1612 if (TargetTriple.isRISCV()) {
1613 Type *OffsetTy = OffsetOp->getType();
1614 // RVV indexed loads/stores zero-extend offset operands which are narrower
1615 // than XLEN to XLEN.
1616 if (OffsetTy->getScalarType()->getIntegerBitWidth() <
1617 static_cast<unsigned>(LongSize)) {
1618 VectorType *OrigType = cast<VectorType>(OffsetTy);
1619 Type *ExtendTy = VectorType::get(IntptrTy, OrigType);
1620 OffsetOp = IB.CreateZExt(OffsetOp, ExtendTy);
1621 }
1622 }
1623 Addr = IB.CreateGEP(Ty, Addr, {OffsetOp});
1624 }
1625
1626 unsigned Granularity = 1 << Mapping.Scale;
1627 if (O.MaybeMask) {
1628 instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.MaybeEVL,
1629 O.MaybeStride, O.getInsn(), Addr, O.Alignment,
1630 Granularity, O.OpType, O.IsWrite, nullptr,
1631 UseCalls, Exp, RTCI);
1632 } else {
1633 doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment,
1634 Granularity, O.TypeStoreSize, O.IsWrite, nullptr,
1635 UseCalls, Exp, RTCI);
1636 }
1637}
1638
1639Instruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore,
1640 Value *Addr, bool IsWrite,
1641 size_t AccessSizeIndex,
1642 Value *SizeArgument,
1643 uint32_t Exp,
1644 RuntimeCallInserter &RTCI) {
1645 InstrumentationIRBuilder IRB(InsertBefore);
1646 Value *ExpVal = Exp == 0 ? nullptr : ConstantInt::get(IRB.getInt32Ty(), Exp);
1647 CallInst *Call = nullptr;
1648 if (SizeArgument) {
1649 if (Exp == 0)
1650 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1651 {Addr, SizeArgument});
1652 else
1653 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1654 {Addr, SizeArgument, ExpVal});
1655 } else {
1656 if (Exp == 0)
1657 Call = RTCI.createRuntimeCall(
1658 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1659 else
1660 Call = RTCI.createRuntimeCall(
1661 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1662 }
1663
1665 return Call;
1666}
1667
1668Value *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong,
1669 Value *ShadowValue,
1670 uint32_t TypeStoreSize) {
1671 size_t Granularity = static_cast<size_t>(1) << Mapping.Scale;
1672 // Addr & (Granularity - 1)
1673 Value *LastAccessedByte =
1674 IRB.CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1675 // (Addr & (Granularity - 1)) + size - 1
1676 if (TypeStoreSize / 8 > 1)
1677 LastAccessedByte = IRB.CreateAdd(
1678 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1679 // (uint8_t) ((Addr & (Granularity-1)) + size - 1)
1680 LastAccessedByte =
1681 IRB.CreateIntCast(LastAccessedByte, ShadowValue->getType(), false);
1682 // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue
1683 return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue);
1684}
1685
1686Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1687 Instruction *OrigIns, Instruction *InsertBefore, Value *Addr,
1688 uint32_t TypeStoreSize, bool IsWrite, Value *SizeArgument) {
1689 // Do not instrument unsupported addrspaces.
1691 return nullptr;
1692 Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
1693 // Follow host instrumentation for global and constant addresses.
1694 if (PtrTy->getPointerAddressSpace() != 0)
1695 return InsertBefore;
1696 // Instrument generic addresses in supported addressspaces.
1697 IRBuilder<> IRB(InsertBefore);
1698 Value *IsShared = IRB.CreateCall(AMDGPUAddressShared, {Addr});
1699 Value *IsPrivate = IRB.CreateCall(AMDGPUAddressPrivate, {Addr});
1700 Value *IsSharedOrPrivate = IRB.CreateOr(IsShared, IsPrivate);
1701 Value *Cmp = IRB.CreateNot(IsSharedOrPrivate);
1702 Value *AddrSpaceZeroLanding =
1703 SplitBlockAndInsertIfThen(Cmp, InsertBefore, false);
1704 InsertBefore = cast<Instruction>(AddrSpaceZeroLanding);
1705 return InsertBefore;
1706}
1707
1708Instruction *AddressSanitizer::genAMDGPUReportBlock(IRBuilder<> &IRB,
1709 Value *Cond, bool Recover) {
1710 Value *ReportCond = Cond;
1711 if (!Recover) {
1712 auto Ballot = Inserter.insertFunction(kAMDGPUBallotName, IRB.getInt64Ty(),
1713 IRB.getInt1Ty());
1714 ReportCond = IRB.CreateIsNotNull(IRB.CreateCall(Ballot, {Cond}));
1715 }
1716
1717 auto *Trm =
1718 SplitBlockAndInsertIfThen(ReportCond, &*IRB.GetInsertPoint(), false,
1720 Trm->getParent()->setName("asan.report");
1721
1722 if (Recover)
1723 return Trm;
1724
1725 Trm = SplitBlockAndInsertIfThen(Cond, Trm, false);
1726 IRB.SetInsertPoint(Trm);
1727 return IRB.CreateCall(
1728 Inserter.insertFunction(kAMDGPUUnreachableName, IRB.getVoidTy()), {});
1729}
1730
1731void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
1732 Instruction *InsertBefore, Value *Addr,
1733 MaybeAlign Alignment,
1734 uint32_t TypeStoreSize, bool IsWrite,
1735 Value *SizeArgument, bool UseCalls,
1736 uint32_t Exp,
1737 RuntimeCallInserter &RTCI) {
1738 if (TargetTriple.isAMDGPU()) {
1739 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1740 TypeStoreSize, IsWrite, SizeArgument);
1741 if (!InsertBefore)
1742 return;
1743 }
1744
1745 InstrumentationIRBuilder IRB(InsertBefore);
1746 size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
1747
1748 if (UseCalls && Opts.asan_optimize_callbacks) {
1749 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1750 IRB.CreateIntrinsic(Intrinsic::asan_check_memaccess, {},
1751 {IRB.CreatePointerCast(Addr, PtrTy),
1752 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
1753 return;
1754 }
1755
1756 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
1757 if (UseCalls) {
1758 if (Exp == 0)
1759 RTCI.createRuntimeCall(
1760 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1761 else
1762 RTCI.createRuntimeCall(
1763 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1764 {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)});
1765 return;
1766 }
1767
1768 Type *ShadowTy =
1769 IntegerType::get(*C, std::max(8U, TypeStoreSize >> Mapping.Scale));
1770 Type *ShadowPtrTy = PointerType::get(*C, Opts.asan_shadow_addr_space);
1771 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1772 const uint64_t ShadowAlign =
1773 std::max<uint64_t>(Alignment.valueOrOne().value() >> Mapping.Scale, 1);
1774 Value *ShadowValue = IRB.CreateAlignedLoad(
1775 ShadowTy, IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy), Align(ShadowAlign));
1776
1777 Value *Cmp = IRB.CreateIsNotNull(ShadowValue);
1778 size_t Granularity = 1ULL << Mapping.Scale;
1779 Instruction *CrashTerm = nullptr;
1780
1781 bool GenSlowPath =
1782 (Opts.asan_always_slow_path || (TypeStoreSize < 8 * Granularity));
1783
1784 if (TargetTriple.isAMDGCN()) {
1785 if (GenSlowPath) {
1786 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1787 Cmp = IRB.CreateAnd(Cmp, Cmp2);
1788 }
1789 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
1790 } else if (GenSlowPath) {
1791 // We use branch weights for the slow path check, to indicate that the slow
1792 // path is rarely taken. This seems to be the case for SPEC benchmarks.
1794 Cmp, InsertBefore, false, MDBuilder(*C).createUnlikelyBranchWeights());
1795 BasicBlock *NextBB = cast<UncondBrInst>(CheckTerm)->getSuccessor();
1796 IRB.SetInsertPoint(CheckTerm);
1797 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1798 if (Recover) {
1799 CrashTerm = SplitBlockAndInsertIfThen(Cmp2, CheckTerm, false);
1800 } else {
1801 BasicBlock *CrashBlock =
1802 BasicBlock::Create(*C, "", NextBB->getParent(), NextBB);
1803 CrashTerm = new UnreachableInst(*C, CrashBlock);
1804 CondBrInst *NewTerm = CondBrInst::Create(Cmp2, CrashBlock, NextBB);
1805 ReplaceInstWithInst(CheckTerm, NewTerm);
1806 }
1807 } else {
1808 CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, !Recover);
1809 }
1810
1811 Instruction *Crash = generateCrashCode(
1812 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
1813 if (OrigIns->getDebugLoc())
1814 Crash->setDebugLoc(OrigIns->getDebugLoc());
1815}
1816
1817// Instrument unusual size or unusual alignment.
1818// We can not do it with a single check, so we do 1-byte check for the first
1819// and the last bytes. We call __asan_report_*_n(addr, real_size) to be able
1820// to report the actual access size.
1821void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1822 Instruction *I, Instruction *InsertBefore, Value *Addr,
1823 TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls,
1824 uint32_t Exp, RuntimeCallInserter &RTCI) {
1825 InstrumentationIRBuilder IRB(InsertBefore);
1826 Value *NumBits = IRB.CreateTypeSize(IntptrTy, TypeStoreSize);
1827 Value *Size = IRB.CreateLShr(NumBits, ConstantInt::get(IntptrTy, 3));
1828
1829 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
1830 if (UseCalls) {
1831 if (Exp == 0)
1832 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
1833 {AddrLong, Size});
1834 else
1835 RTCI.createRuntimeCall(
1836 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
1837 {AddrLong, Size, ConstantInt::get(IRB.getInt32Ty(), Exp)});
1838 } else {
1839 Value *SizeMinusOne = IRB.CreateSub(Size, ConstantInt::get(IntptrTy, 1));
1840 Value *LastByte = IRB.CreateIntToPtr(
1841 IRB.CreateAdd(AddrLong, SizeMinusOne),
1842 Addr->getType());
1843 instrumentAddress(I, InsertBefore, Addr, {}, 8, IsWrite, Size, false, Exp,
1844 RTCI);
1845 instrumentAddress(I, InsertBefore, LastByte, {}, 8, IsWrite, Size, false,
1846 Exp, RTCI);
1847 }
1848}
1849
1850void ModuleAddressSanitizer::poisonOneInitializer(Function &GlobalInit) {
1851 // Set up the arguments to our poison/unpoison functions.
1852 IRBuilder<> IRB(GlobalInit.front().getFirstInsertionPt());
1853
1854 // Add a call to poison all external globals before the given function starts.
1855 Value *ModuleNameAddr =
1856 ConstantExpr::getPointerCast(getOrCreateModuleName(), IntptrTy);
1857 CallInst *CallBefore = IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr);
1858 if (DISubprogram *SP = GlobalInit.getSubprogram())
1859 CallBefore->setDebugLoc(
1860 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
1861
1862 // Add calls to unpoison all globals before each return instruction.
1863 for (auto &BB : GlobalInit)
1865 CallInst *CallAfter =
1866 CallInst::Create(AsanUnpoisonGlobals, "", RI->getIterator());
1867 if (RI->getDebugLoc())
1868 CallAfter->setDebugLoc(RI->getDebugLoc());
1869 else if (DISubprogram *SP = GlobalInit.getSubprogram())
1870 CallAfter->setDebugLoc(
1871 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
1872 }
1873}
1874
1875void ModuleAddressSanitizer::createInitializerPoisonCalls() {
1876 GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
1877 if (!GV)
1878 return;
1879
1881 if (!CA)
1882 return;
1883
1884 for (Use &OP : CA->operands()) {
1885 if (isa<ConstantAggregateZero>(OP)) continue;
1887
1888 // Must have a function or null ptr.
1889 if (Function *F = dyn_cast<Function>(CS->getOperand(1))) {
1890 if (F->getName() == kAsanModuleCtorName) continue;
1891 auto *Priority = cast<ConstantInt>(CS->getOperand(0));
1892 // Don't instrument CTORs that will run before asan.module_ctor.
1893 if (Priority->getLimitedValue() <= GetCtorAndDtorPriority(TargetTriple))
1894 continue;
1895 poisonOneInitializer(*F);
1896 }
1897 }
1898}
1899
1900const GlobalVariable *
1901ModuleAddressSanitizer::getExcludedAliasedGlobal(const GlobalAlias &GA) const {
1902 // In case this function should be expanded to include rules that do not just
1903 // apply when CompileKernel is true, either guard all existing rules with an
1904 // 'if (CompileKernel) { ... }' or be absolutely sure that all these rules
1905 // should also apply to user space.
1906 assert(CompileKernel && "Only expecting to be called when compiling kernel");
1907
1908 const Constant *C = GA.getAliasee();
1909
1910 // When compiling the kernel, globals that are aliased by symbols prefixed
1911 // by "__" are special and cannot be padded with a redzone.
1912 if (GA.getName().starts_with("__"))
1913 return dyn_cast<GlobalVariable>(C->stripPointerCastsAndAliases());
1914
1915 return nullptr;
1916}
1917
1918bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
1919 Type *Ty = G->getValueType();
1920 LLVM_DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
1921
1922 if (G->hasSanitizerMetadata() && G->getSanitizerMetadata().NoAddress)
1923 return false;
1924 if (!Ty->isSized()) return false;
1925 if (!G->hasInitializer()) return false;
1926 if (!isSupportedAddrspace(Opts, TargetTriple, G))
1927 return false;
1928 if (GlobalWasGeneratedByCompiler(G)) return false; // Our own globals.
1929 // Two problems with thread-locals:
1930 // - The address of the main thread's copy can't be computed at link-time.
1931 // - Need to poison all copies, not just the main thread's one.
1932 if (G->isThreadLocal()) return false;
1933 // For now, just ignore this Global if the alignment is large.
1934 if (G->getAlign() && *G->getAlign() > getMinRedzoneSizeForGlobal()) return false;
1935
1936 // For non-COFF targets, only instrument globals known to be defined by this
1937 // TU.
1938 // FIXME: We can instrument comdat globals on ELF if we are using the
1939 // GC-friendly metadata scheme.
1940 if (!TargetTriple.isOSBinFormatCOFF()) {
1941 if (!G->hasExactDefinition() || G->hasComdat())
1942 return false;
1943 } else {
1944 // On COFF, don't instrument non-ODR linkages.
1945 if (G->isInterposable())
1946 return false;
1947 // If the global has AvailableExternally linkage, then it is not in this
1948 // module, which means it does not need to be instrumented.
1949 if (G->hasAvailableExternallyLinkage())
1950 return false;
1951 }
1952
1953 // If a comdat is present, it must have a selection kind that implies ODR
1954 // semantics: no duplicates, any, or exact match.
1955 if (Comdat *C = G->getComdat()) {
1956 switch (C->getSelectionKind()) {
1957 case Comdat::Any:
1958 case Comdat::ExactMatch:
1960 break;
1961 case Comdat::Largest:
1962 case Comdat::SameSize:
1963 return false;
1964 }
1965 }
1966
1967 if (G->hasSection()) {
1968 // The kernel uses explicit sections for mostly special global variables
1969 // that we should not instrument. E.g. the kernel may rely on their layout
1970 // without redzones, or remove them at link time ("discard.*"), etc.
1971 if (CompileKernel)
1972 return false;
1973
1974 StringRef Section = G->getSection();
1975
1976 // Globals from llvm.metadata aren't emitted, do not instrument them.
1977 if (Section == "llvm.metadata") return false;
1978 // Do not instrument globals from special LLVM sections.
1979 if (Section.contains("__llvm") || Section.contains("__LLVM"))
1980 return false;
1981
1982 // Do not instrument function pointers to initialization and termination
1983 // routines: dynamic linker will not properly handle redzones.
1984 if (Section.starts_with(".preinit_array") ||
1985 Section.starts_with(".init_array") ||
1986 Section.starts_with(".fini_array")) {
1987 return false;
1988 }
1989
1990 // Do not instrument user-defined sections (with names resembling
1991 // valid C identifiers)
1992 if (TargetTriple.isOSBinFormatELF()) {
1993 if (llvm::all_of(Section,
1994 [](char c) { return llvm::isAlnum(c) || c == '_'; }))
1995 return false;
1996 }
1997
1998 // On COFF, if the section name contains '$', it is highly likely that the
1999 // user is using section sorting to create an array of globals similar to
2000 // the way initialization callbacks are registered in .init_array and
2001 // .CRT$XCU. The ATL also registers things in .ATL$__[azm]. Adding redzones
2002 // to such globals is counterproductive, because the intent is that they
2003 // will form an array, and out-of-bounds accesses are expected.
2004 // See https://github.com/google/sanitizers/issues/305
2005 // and http://msdn.microsoft.com/en-US/en-en/library/bb918180(v=vs.120).aspx
2006 if (TargetTriple.isOSBinFormatCOFF() && Section.contains('$')) {
2007 LLVM_DEBUG(dbgs() << "Ignoring global in sorted section (contains '$'): "
2008 << *G << "\n");
2009 return false;
2010 }
2011
2012 if (TargetTriple.isOSBinFormatMachO()) {
2013 StringRef ParsedSegment, ParsedSection;
2014 unsigned TAA = 0, StubSize = 0;
2015 bool TAAParsed;
2017 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2018
2019 // Ignore the globals from the __OBJC section. The ObjC runtime assumes
2020 // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to
2021 // them.
2022 if (ParsedSegment == "__OBJC" ||
2023 (ParsedSegment == "__DATA" && ParsedSection.starts_with("__objc_"))) {
2024 LLVM_DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n");
2025 return false;
2026 }
2027 // See https://github.com/google/sanitizers/issues/32
2028 // Constant CFString instances are compiled in the following way:
2029 // -- the string buffer is emitted into
2030 // __TEXT,__cstring,cstring_literals
2031 // -- the constant NSConstantString structure referencing that buffer
2032 // is placed into __DATA,__cfstring
2033 // Therefore there's no point in placing redzones into __DATA,__cfstring.
2034 // Moreover, it causes the linker to crash on OS X 10.7
2035 if (ParsedSegment == "__DATA" && ParsedSection == "__cfstring") {
2036 LLVM_DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n");
2037 return false;
2038 }
2039 // The linker merges the contents of cstring_literals and removes the
2040 // trailing zeroes.
2041 if (ParsedSegment == "__TEXT" && (TAA & MachO::S_CSTRING_LITERALS)) {
2042 LLVM_DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n");
2043 return false;
2044 }
2045 }
2046 }
2047
2048 if (CompileKernel) {
2049 // Globals that prefixed by "__" are special and cannot be padded with a
2050 // redzone.
2051 if (G->getName().starts_with("__"))
2052 return false;
2053 }
2054
2055 return true;
2056}
2057
2058// On Mach-O platforms, we emit global metadata in a separate section of the
2059// binary in order to allow the linker to properly dead strip. This is only
2060// supported on recent versions of ld64.
2061bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection() const {
2062 if (!TargetTriple.isOSBinFormatMachO())
2063 return false;
2064
2065 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2066 return true;
2067 if (TargetTriple.isiOS() /* or tvOS */ && !TargetTriple.isOSVersionLT(9))
2068 return true;
2069 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2070 return true;
2071 if (TargetTriple.isDriverKit())
2072 return true;
2073 if (TargetTriple.isXROS())
2074 return true;
2075
2076 return false;
2077}
2078
2079StringRef ModuleAddressSanitizer::getGlobalMetadataSection() const {
2080 switch (TargetTriple.getObjectFormat()) {
2081 case Triple::COFF: return ".ASAN$GL";
2082 case Triple::ELF: return "asan_globals";
2083 case Triple::MachO: return "__DATA,__asan_globals,regular";
2084 case Triple::Wasm:
2085 case Triple::GOFF:
2086 case Triple::SPIRV:
2087 case Triple::XCOFF:
2090 "ModuleAddressSanitizer not implemented for object file format");
2092 break;
2093 }
2094 llvm_unreachable("unsupported object format");
2095}
2096
2097void ModuleAddressSanitizer::initializeCallbacks() {
2098 IRBuilder<> IRB(M);
2099
2100 // Declare our poisoning and unpoisoning functions.
2101 AsanPoisonGlobals = Inserter.insertFunction(kAsanPoisonGlobalsName,
2102 IRB.getVoidTy(), IntptrTy);
2103 AsanUnpoisonGlobals =
2104 Inserter.insertFunction(kAsanUnpoisonGlobalsName, IRB.getVoidTy());
2105
2106 // Declare functions that register/unregister globals.
2107 AsanRegisterGlobals = Inserter.insertFunction(
2108 kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy);
2109 AsanUnregisterGlobals = Inserter.insertFunction(
2110 kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy);
2111
2112 // Declare the functions that find globals in a shared object and then invoke
2113 // the (un)register function on them.
2114 AsanRegisterImageGlobals = Inserter.insertFunction(
2115 kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy);
2116 AsanUnregisterImageGlobals = Inserter.insertFunction(
2118
2119 AsanRegisterElfGlobals =
2120 Inserter.insertFunction(kAsanRegisterElfGlobalsName, IRB.getVoidTy(),
2121 IntptrTy, IntptrTy, IntptrTy);
2122 AsanUnregisterElfGlobals =
2123 Inserter.insertFunction(kAsanUnregisterElfGlobalsName, IRB.getVoidTy(),
2124 IntptrTy, IntptrTy, IntptrTy);
2125}
2126
2127// Put the metadata and the instrumented global in the same group. This ensures
2128// that the metadata is discarded if the instrumented global is discarded.
2129void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2130 GlobalVariable *G, GlobalVariable *Metadata, StringRef InternalSuffix) {
2131 Module &M = *G->getParent();
2132 Comdat *C = G->getComdat();
2133 if (!C) {
2134 if (!G->hasName()) {
2135 // If G is unnamed, it must be internal. Give it an artificial name
2136 // so we can put it in a comdat.
2137 assert(G->hasLocalLinkage());
2138 G->setName(genName("anon_global"));
2139 }
2140
2141 if (!InternalSuffix.empty() && G->hasLocalLinkage()) {
2142 std::string Name = std::string(G->getName());
2143 Name += InternalSuffix;
2144 C = M.getOrInsertComdat(Name);
2145 } else {
2146 C = M.getOrInsertComdat(G->getName());
2147 }
2148
2149 // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. Also upgrade private
2150 // linkage to internal linkage so that a symbol table entry is emitted. This
2151 // is necessary in order to create the comdat group.
2152 if (TargetTriple.isOSBinFormatCOFF()) {
2153 C->setSelectionKind(Comdat::NoDeduplicate);
2154 if (G->hasPrivateLinkage())
2155 G->setLinkage(GlobalValue::InternalLinkage);
2156 }
2157 G->setComdat(C);
2158 }
2159
2160 assert(G->hasComdat());
2161 Metadata->setComdat(G->getComdat());
2162}
2163
2164// Create a separate metadata global and put it in the appropriate ASan
2165// global registration section.
2167ModuleAddressSanitizer::CreateMetadataGlobal(Constant *Initializer,
2168 StringRef OriginalName) {
2169 auto Linkage = TargetTriple.isOSBinFormatMachO()
2173 M, Initializer->getType(), false, Linkage, Initializer,
2174 Twine("__asan_global_") + GlobalValue::dropLLVMManglingEscape(OriginalName));
2175 Metadata->setSection(getGlobalMetadataSection());
2176 // Place metadata in a large section for x86-64 ELF binaries to mitigate
2177 // relocation pressure.
2179 return Metadata;
2180}
2181
2182Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2183 AsanDtorFunction = Function::createWithDefaultAttr(
2186 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2187 // Ensure Dtor cannot be discarded, even if in a comdat.
2188 appendToUsed(M, {AsanDtorFunction});
2189 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
2190
2191 return ReturnInst::Create(*C, AsanDtorBB);
2192}
2193
2194void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2195 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2196 ArrayRef<Constant *> MetadataInitializers) {
2197 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2198 auto &DL = M.getDataLayout();
2199
2200 SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
2201 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2202 Constant *Initializer = MetadataInitializers[i];
2203 GlobalVariable *G = ExtendedGlobals[i];
2204 GlobalVariable *Metadata = CreateMetadataGlobal(Initializer, G->getName());
2205 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
2206 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2207 MetadataGlobals[i] = Metadata;
2208
2209 // The MSVC linker always inserts padding when linking incrementally. We
2210 // cope with that by aligning each struct to its size, which must be a power
2211 // of two.
2212 unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
2213 assert(isPowerOf2_32(SizeOfGlobalStruct) &&
2214 "global metadata will not be padded appropriately");
2215 Metadata->setAlignment(assumeAligned(SizeOfGlobalStruct));
2216
2217 SetComdatForGlobalMetadata(G, Metadata, "");
2218 }
2219
2220 // Update llvm.compiler.used, adding the new metadata globals. This is
2221 // needed so that during LTO these variables stay alive.
2222 if (!MetadataGlobals.empty())
2223 appendToCompilerUsed(M, MetadataGlobals);
2224}
2225
2226void ModuleAddressSanitizer::instrumentGlobalsELF(
2227 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2228 ArrayRef<Constant *> MetadataInitializers,
2229 const std::string &UniqueModuleId) {
2230 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2231
2232 // Putting globals in a comdat changes the semantic and potentially cause
2233 // false negative odr violations at link time. If odr indicators are used, we
2234 // keep the comdat sections, as link time odr violations will be detected on
2235 // the odr indicator symbols.
2236 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2237
2238 SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
2239 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2240 GlobalVariable *G = ExtendedGlobals[i];
2242 CreateMetadataGlobal(MetadataInitializers[i], G->getName());
2243 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
2244 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2245 MetadataGlobals[i] = Metadata;
2246
2247 if (UseComdatForGlobalsGC)
2248 SetComdatForGlobalMetadata(G, Metadata, UniqueModuleId);
2249 }
2250
2251 // Update llvm.compiler.used, adding the new metadata globals. This is
2252 // needed so that during LTO these variables stay alive.
2253 if (!MetadataGlobals.empty())
2254 appendToCompilerUsed(M, MetadataGlobals);
2255
2256 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
2257 // to look up the loaded image that contains it. Second, we can store in it
2258 // whether registration has already occurred, to prevent duplicate
2259 // registration.
2260 //
2261 // Common linkage ensures that there is only one global per shared library.
2262 GlobalVariable *RegisteredFlag = new GlobalVariable(
2263 M, IntptrTy, false, GlobalVariable::CommonLinkage,
2264 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
2266
2267 // Create start and stop symbols.
2268 GlobalVariable *StartELFMetadata = new GlobalVariable(
2269 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2270 "__start_" + getGlobalMetadataSection());
2272 GlobalVariable *StopELFMetadata = new GlobalVariable(
2273 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2274 "__stop_" + getGlobalMetadataSection());
2276
2277 // Create a call to register the globals with the runtime.
2278 if (ConstructorKind == AsanCtorKind::Global)
2279 IRB.CreateCall(AsanRegisterElfGlobals,
2280 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
2281 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
2282 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
2283
2284 // We also need to unregister globals at the end, e.g., when a shared library
2285 // gets closed.
2286 if (DestructorKind != AsanDtorKind::None && !MetadataGlobals.empty()) {
2287 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2288 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2289 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
2290 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
2291 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
2292 }
2293}
2294
2295void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2296 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2297 ArrayRef<Constant *> MetadataInitializers) {
2298 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2299
2300 // On recent Mach-O platforms, use a structure which binds the liveness of
2301 // the global variable to the metadata struct. Keep the list of "Liveness" GV
2302 // created to be added to llvm.compiler.used
2303 StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy);
2304 SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
2305
2306 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2307 Constant *Initializer = MetadataInitializers[i];
2308 GlobalVariable *G = ExtendedGlobals[i];
2309 GlobalVariable *Metadata = CreateMetadataGlobal(Initializer, G->getName());
2310
2311 // On recent Mach-O platforms, we emit the global metadata in a way that
2312 // allows the linker to properly strip dead globals.
2313 auto LivenessBinder =
2314 ConstantStruct::get(LivenessTy, Initializer->getAggregateElement(0u),
2316 GlobalVariable *Liveness = new GlobalVariable(
2317 M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
2318 Twine("__asan_binder_") + G->getName());
2319 Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
2320 LivenessGlobals[i] = Liveness;
2321 }
2322
2323 // Update llvm.compiler.used, adding the new liveness globals. This is
2324 // needed so that during LTO these variables stay alive. The alternative
2325 // would be to have the linker handling the LTO symbols, but libLTO
2326 // current API does not expose access to the section for each symbol.
2327 if (!LivenessGlobals.empty())
2328 appendToCompilerUsed(M, LivenessGlobals);
2329
2330 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
2331 // to look up the loaded image that contains it. Second, we can store in it
2332 // whether registration has already occurred, to prevent duplicate
2333 // registration.
2334 //
2335 // common linkage ensures that there is only one global per shared library.
2336 GlobalVariable *RegisteredFlag = new GlobalVariable(
2337 M, IntptrTy, false, GlobalVariable::CommonLinkage,
2338 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
2340
2341 if (ConstructorKind == AsanCtorKind::Global)
2342 IRB.CreateCall(AsanRegisterImageGlobals,
2343 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
2344
2345 // We also need to unregister globals at the end, e.g., when a shared library
2346 // gets closed.
2347 if (DestructorKind != AsanDtorKind::None) {
2348 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2349 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2350 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
2351 }
2352}
2353
2354void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2355 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2356 ArrayRef<Constant *> MetadataInitializers) {
2357 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2358 unsigned N = ExtendedGlobals.size();
2359 assert(N > 0);
2360
2361 // On platforms that don't have a custom metadata section, we emit an array
2362 // of global metadata structures.
2363 ArrayType *ArrayOfGlobalStructTy =
2364 ArrayType::get(MetadataInitializers[0]->getType(), N);
2365 auto AllGlobals = new GlobalVariable(
2366 M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
2367 ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
2368 if (Mapping.Scale > 3)
2369 AllGlobals->setAlignment(Align::fromLog2(Mapping.Scale));
2370
2371 if (ConstructorKind == AsanCtorKind::Global)
2372 IRB.CreateCall(AsanRegisterGlobals,
2373 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
2374 ConstantInt::get(IntptrTy, N)});
2375
2376 // We also need to unregister globals at the end, e.g., when a shared library
2377 // gets closed.
2378 if (DestructorKind != AsanDtorKind::None) {
2379 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2380 IrbDtor.CreateCall(AsanUnregisterGlobals,
2381 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
2382 ConstantInt::get(IntptrTy, N)});
2383 }
2384}
2385
2386// This function replaces all global variables with new variables that have
2387// trailing redzones. It also creates a function that poisons
2388// redzones and inserts this function into llvm.global_ctors.
2389// Sets *CtorComdat to true if the global registration code emitted into the
2390// asan constructor is comdat-compatible.
2391void ModuleAddressSanitizer::instrumentGlobals(IRBuilder<> &IRB,
2392 bool *CtorComdat) {
2393 // Build set of globals that are aliased by some GA, where
2394 // getExcludedAliasedGlobal(GA) returns the relevant GlobalVariable.
2395 SmallPtrSet<const GlobalVariable *, 16> AliasedGlobalExclusions;
2396 if (CompileKernel) {
2397 for (auto &GA : M.aliases()) {
2398 if (const GlobalVariable *GV = getExcludedAliasedGlobal(GA))
2399 AliasedGlobalExclusions.insert(GV);
2400 }
2401 }
2402
2403 SmallVector<GlobalVariable *, 16> GlobalsToChange;
2404 for (auto &G : M.globals()) {
2405 if (!AliasedGlobalExclusions.count(&G) && shouldInstrumentGlobal(&G))
2406 GlobalsToChange.push_back(&G);
2407 }
2408
2409 size_t n = GlobalsToChange.size();
2410 auto &DL = M.getDataLayout();
2411
2412 // A global is described by a structure
2413 // size_t beg;
2414 // size_t size;
2415 // size_t size_with_redzone;
2416 // const char *name;
2417 // const char *module_name;
2418 // size_t has_dynamic_init;
2419 // size_t padding_for_windows_msvc_incremental_link;
2420 // size_t odr_indicator;
2421 // We initialize an array of such structures and pass it to a run-time call.
2422 StructType *GlobalStructTy =
2423 StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
2424 IntptrTy, IntptrTy, IntptrTy);
2426 SmallVector<Constant *, 16> Initializers(n);
2427
2428 for (size_t i = 0; i < n; i++) {
2429 GlobalVariable *G = GlobalsToChange[i];
2430
2432 if (G->hasSanitizerMetadata())
2433 MD = G->getSanitizerMetadata();
2434
2435 // The runtime library tries demangling symbol names in the descriptor but
2436 // functionality like __cxa_demangle may be unavailable (e.g.
2437 // -static-libstdc++). So we demangle the symbol names here.
2438 std::string NameForGlobal = G->getName().str();
2441 /*AllowMerging*/ true, genName("global"));
2442
2443 Type *Ty = G->getValueType();
2444 const uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
2445 const uint64_t RightRedzoneSize = getRedzoneSizeForGlobal(SizeInBytes);
2446 Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
2447
2448 StructType *NewTy = StructType::get(Ty, RightRedZoneTy);
2449 Constant *NewInitializer = ConstantStruct::get(
2450 NewTy, G->getInitializer(), Constant::getNullValue(RightRedZoneTy));
2451
2452 // Create a new global variable with enough space for a redzone.
2453 GlobalValue::LinkageTypes Linkage = G->getLinkage();
2454 if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage)
2456 GlobalVariable *NewGlobal = new GlobalVariable(
2457 M, NewTy, G->isConstant(), Linkage, NewInitializer, "", G,
2458 G->getThreadLocalMode(), G->getAddressSpace());
2459 NewGlobal->copyAttributesFrom(G);
2460 NewGlobal->setComdat(G->getComdat());
2461 NewGlobal->setAlignment(Align(getMinRedzoneSizeForGlobal()));
2462 // Don't fold globals with redzones. ODR violation detector and redzone
2463 // poisoning implicitly creates a dependence on the global's address, so it
2464 // is no longer valid for it to be marked unnamed_addr.
2466
2467 // Move null-terminated C strings to "__asan_cstring" section on Darwin.
2468 if (TargetTriple.isOSBinFormatMachO() && !G->hasSection() &&
2469 G->isConstant()) {
2470 auto Seq = dyn_cast<ConstantDataSequential>(G->getInitializer());
2471 if (Seq && Seq->isCString())
2472 NewGlobal->setSection("__TEXT,__asan_cstring,regular");
2473 }
2474
2475 // Transfer the debug info and type metadata. The payload starts at offset
2476 // zero so we can copy the metadata over as is.
2477 NewGlobal->copyMetadata(G, 0);
2478
2479 G->replaceAllUsesWith(NewGlobal);
2480 NewGlobal->takeName(G);
2481 G->eraseFromParent();
2482 NewGlobals[i] = NewGlobal;
2483
2484 Constant *ODRIndicator = Constant::getNullValue(IntptrTy);
2485 GlobalValue *InstrumentedGlobal = NewGlobal;
2486
2487 bool CanUsePrivateAliases =
2488 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2489 TargetTriple.isOSBinFormatWasm();
2490 if (CanUsePrivateAliases && UsePrivateAlias) {
2491 // Create local alias for NewGlobal to avoid crash on ODR between
2492 // instrumented and non-instrumented libraries.
2493 InstrumentedGlobal =
2495 }
2496
2497 // ODR should not happen for local linkage.
2498 if (NewGlobal->hasLocalLinkage()) {
2499 ODRIndicator = ConstantInt::getAllOnesValue(IntptrTy);
2500 } else if (UseOdrIndicator) {
2501 // With local aliases, we need to provide another externally visible
2502 // symbol __odr_asan_XXX to detect ODR violation.
2503 auto *ODRIndicatorSym =
2504 new GlobalVariable(M, IRB.getInt8Ty(), false, Linkage,
2506 kODRGenPrefix + NameForGlobal, nullptr,
2507 NewGlobal->getThreadLocalMode());
2508
2509 // Set meaningful attributes for indicator symbol.
2510 ODRIndicatorSym->setVisibility(NewGlobal->getVisibility());
2511 ODRIndicatorSym->setDLLStorageClass(NewGlobal->getDLLStorageClass());
2512 ODRIndicatorSym->setAlignment(Align(1));
2513 ODRIndicator = ConstantExpr::getPtrToInt(ODRIndicatorSym, IntptrTy);
2514 }
2515
2516 Constant *Initializer = ConstantStruct::get(
2517 GlobalStructTy,
2518 ConstantExpr::getPointerCast(InstrumentedGlobal, IntptrTy),
2519 ConstantInt::get(IntptrTy, SizeInBytes),
2520 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2521 ConstantExpr::getPointerCast(Name, IntptrTy),
2522 ConstantExpr::getPointerCast(getOrCreateModuleName(), IntptrTy),
2523 ConstantInt::get(IntptrTy, MD.IsDynInit),
2524 Constant::getNullValue(IntptrTy), ODRIndicator);
2525
2526 LLVM_DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
2527
2528 Initializers[i] = Initializer;
2529 }
2530
2531 // Add instrumented globals to llvm.compiler.used list to avoid LTO from
2532 // ConstantMerge'ing them.
2533 SmallVector<GlobalValue *, 16> GlobalsToAddToUsedList;
2534 for (size_t i = 0; i < n; i++) {
2535 GlobalVariable *G = NewGlobals[i];
2536 if (G->getName().empty()) continue;
2537 GlobalsToAddToUsedList.push_back(G);
2538 }
2539 appendToCompilerUsed(M, ArrayRef<GlobalValue *>(GlobalsToAddToUsedList));
2540
2541 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2542 // Use COMDAT and register globals even if n == 0 to ensure that (a) the
2543 // linkage unit will only have one module constructor, and (b) the register
2544 // function will be called. The module destructor is not created when n ==
2545 // 0.
2546 *CtorComdat = true;
2547 instrumentGlobalsELF(IRB, NewGlobals, Initializers, getUniqueModuleId(&M));
2548 } else if (n == 0) {
2549 // When UseGlobalsGC is false, COMDAT can still be used if n == 0, because
2550 // all compile units will have identical module constructor/destructor.
2551 *CtorComdat = TargetTriple.isOSBinFormatELF();
2552 } else {
2553 *CtorComdat = false;
2554 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2555 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2556 } else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2557 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2558 } else {
2559 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2560 }
2561 }
2562
2563 // Create calls for poisoning before initializers run and unpoisoning after.
2564 if (Opts.asan_initialization_order)
2565 createInitializerPoisonCalls();
2566
2567 LLVM_DEBUG(dbgs() << M);
2568}
2569
2571ModuleAddressSanitizer::getRedzoneSizeForGlobal(uint64_t SizeInBytes) const {
2572 constexpr uint64_t kMaxRZ = 1 << 18;
2573 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2574
2575 uint64_t RZ = 0;
2576 if (SizeInBytes <= MinRZ / 2) {
2577 // Reduce redzone size for small size objects, e.g. int, char[1]. MinRZ is
2578 // at least 32 bytes, optimize when SizeInBytes is less than or equal to
2579 // half of MinRZ.
2580 RZ = MinRZ - SizeInBytes;
2581 } else {
2582 // Calculate RZ, where MinRZ <= RZ <= MaxRZ, and RZ ~ 1/4 * SizeInBytes.
2583 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2584
2585 // Round up to multiple of MinRZ.
2586 if (SizeInBytes % MinRZ)
2587 RZ += MinRZ - (SizeInBytes % MinRZ);
2588 }
2589
2590 assert((RZ + SizeInBytes) % MinRZ == 0);
2591
2592 return RZ;
2593}
2594
2595int ModuleAddressSanitizer::GetAsanVersion() const {
2596 int LongSize = M.getDataLayout().getPointerSizeInBits();
2597 bool isAndroid = M.getTargetTriple().isAndroid();
2598 int Version = 8;
2599 // 32-bit Android is one version ahead because of the switch to dynamic
2600 // shadow.
2601 Version += (LongSize == 32 && isAndroid);
2602 return Version;
2603}
2604
2605GlobalVariable *ModuleAddressSanitizer::getOrCreateModuleName() {
2606 if (!ModuleName) {
2607 // We shouldn't merge same module names, as this string serves as unique
2608 // module ID in runtime.
2609 ModuleName =
2610 createPrivateGlobalForString(M, M.getModuleIdentifier(),
2611 /*AllowMerging*/ false, genName("module"));
2612 }
2613 return ModuleName;
2614}
2615
2616bool ModuleAddressSanitizer::instrumentModule() {
2617 initializeCallbacks();
2618
2619 for (Function &F : M)
2620 removeASanIncompatibleFnAttributes(F, /*ReadsArgMem=*/false);
2621
2622 // Create a module constructor. A destructor is created lazily because not all
2623 // platforms, and not all modules need it.
2624 if (ConstructorKind == AsanCtorKind::Global) {
2625 if (CompileKernel) {
2626 // The kernel always builds with its own runtime, and therefore does not
2627 // need the init and version check calls.
2628 AsanCtorFunction = createSanitizerCtor(M, kAsanModuleCtorName);
2629 } else {
2630 std::string AsanVersion = std::to_string(GetAsanVersion());
2631 std::string VersionCheckName =
2632 InsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : "";
2633 std::tie(AsanCtorFunction, std::ignore) =
2635 M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{},
2636 /*InitArgs=*/{}, VersionCheckName);
2637 }
2638 }
2639
2640 bool CtorComdat = true;
2641 if (Opts.asan_globals) {
2642 assert(AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
2643 if (AsanCtorFunction) {
2644 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2645 instrumentGlobals(IRB, &CtorComdat);
2646 } else {
2647 IRBuilder<> IRB(M);
2648 instrumentGlobals(IRB, &CtorComdat);
2649 }
2650 }
2651
2652 const uint64_t Priority = GetCtorAndDtorPriority(TargetTriple);
2653
2654 // Put the constructor and destructor in comdat if both
2655 // (1) global instrumentation is not TU-specific
2656 // (2) target is ELF.
2657 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2658 if (AsanCtorFunction) {
2659 AsanCtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleCtorName));
2660 appendToGlobalCtors(M, AsanCtorFunction, Priority, AsanCtorFunction);
2661 }
2662 if (AsanDtorFunction) {
2663 AsanDtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleDtorName));
2664 appendToGlobalDtors(M, AsanDtorFunction, Priority, AsanDtorFunction);
2665 }
2666 } else {
2667 if (AsanCtorFunction)
2668 appendToGlobalCtors(M, AsanCtorFunction, Priority);
2669 if (AsanDtorFunction)
2670 appendToGlobalDtors(M, AsanDtorFunction, Priority);
2671 }
2672
2673 return true;
2674}
2675
2676void AddressSanitizer::initializeCallbacks(const TargetLibraryInfo *TLI) {
2677 IRBuilder<> IRB(M);
2678 // Create __asan_report* callbacks.
2679 // IsWrite, TypeSize and Exp are encoded in the function name.
2680 for (int Exp = 0; Exp < 2; Exp++) {
2681 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2682 const std::string TypeStr = AccessIsWrite ? "store" : "load";
2683 const std::string ExpStr = Exp ? "exp_" : "";
2684 const std::string EndingStr = Recover ? "_noabort" : "";
2685
2686 SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
2687 SmallVector<Type *, 2> Args1{1, IntptrTy};
2688 AttributeList AL2;
2689 AttributeList AL1;
2690 if (Exp) {
2691 Type *ExpType = Type::getInt32Ty(*C);
2692 Args2.push_back(ExpType);
2693 Args1.push_back(ExpType);
2694 if (auto AK = TLI->getExtAttrForI32Param(false)) {
2695 AL2 = AL2.addParamAttribute(*C, 2, AK);
2696 AL1 = AL1.addParamAttribute(*C, 1, AK);
2697 }
2698 }
2699 AsanErrorCallbackSized[AccessIsWrite][Exp] = Inserter.insertFunction(
2700 kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr,
2701 FunctionType::get(IRB.getVoidTy(), Args2, false), AL2);
2702
2703 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
2704 Inserter.insertFunction(
2705 (Opts.asan_memory_access_callback_prefix + ExpStr + TypeStr +
2706 "N" + EndingStr)
2707 .str(),
2708 FunctionType::get(IRB.getVoidTy(), Args2, false), AL2);
2709
2710 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
2711 AccessSizeIndex++) {
2712 const std::string Suffix = TypeStr + itostr(1ULL << AccessSizeIndex);
2713 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2714 Inserter.insertFunction(
2715 kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr,
2716 FunctionType::get(IRB.getVoidTy(), Args1, false), AL1);
2717
2718 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2719 Inserter.insertFunction(
2720 (Opts.asan_memory_access_callback_prefix + ExpStr + Suffix +
2721 EndingStr)
2722 .str(),
2723 FunctionType::get(IRB.getVoidTy(), Args1, false), AL1);
2724 }
2725 }
2726 }
2727
2728 const std::string MemIntrinCallbackPrefix =
2729 (CompileKernel && !Opts.asan_kernel_mem_intrinsic_prefix)
2730 ? std::string("")
2731 : Opts.asan_memory_access_callback_prefix.str();
2732 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix + "memmove",
2733 PtrTy, PtrTy, PtrTy, IntptrTy);
2734 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix + "memcpy",
2735 PtrTy, PtrTy, PtrTy, IntptrTy);
2736 AsanMemset =
2737 Inserter.insertFunction(MemIntrinCallbackPrefix + "memset",
2738 TLI->getAttrList(C, {1},
2739 /*Signed=*/false),
2740 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
2741
2742 AsanHandleNoReturnFunc =
2743 Inserter.insertFunction(kAsanHandleNoReturnName, IRB.getVoidTy());
2744
2745 AsanPtrCmpFunction =
2746 Inserter.insertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy);
2747 AsanPtrSubFunction =
2748 Inserter.insertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy);
2749 if (Mapping.InGlobal)
2750 AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow",
2751 ArrayType::get(IRB.getInt8Ty(), 0));
2752
2753 AMDGPUAddressShared =
2754 Inserter.insertFunction(kAMDGPUAddressSharedName, IRB.getInt1Ty(), PtrTy);
2755 AMDGPUAddressPrivate = Inserter.insertFunction(kAMDGPUAddressPrivateName,
2756 IRB.getInt1Ty(), PtrTy);
2757}
2758
2759bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
2760 // For each NSObject descendant having a +load method, this method is invoked
2761 // by the ObjC runtime before any of the static constructors is called.
2762 // Therefore we need to instrument such methods with a call to __asan_init
2763 // at the beginning in order to initialize our runtime before any access to
2764 // the shadow memory.
2765 // We cannot just ignore these methods, because they may call other
2766 // instrumented functions.
2767 if (F.getName().contains(" load]")) {
2768 FunctionCallee AsanInitFunction =
2769 declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {});
2770 IRBuilder<> IRB(F.front().begin());
2771 IRB.CreateCall(AsanInitFunction, {});
2772 return true;
2773 }
2774 return false;
2775}
2776
2777bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(Function &F) {
2778 // Generate code only when dynamic addressing is needed.
2779 if (Mapping.Offset != kDynamicShadowSentinel)
2780 return false;
2781
2782 IRBuilder<> IRB(&F.front().front());
2783 if (Mapping.InGlobal) {
2784 if (Opts.asan_with_ifunc_suppress_remat) {
2785 // An empty inline asm with input reg == output reg.
2786 // An opaque pointer-to-int cast, basically.
2788 FunctionType::get(IntptrTy, {AsanShadowGlobal->getType()}, false),
2789 StringRef(""), StringRef("=r,0"),
2790 /*hasSideEffects=*/false);
2791 LocalDynamicShadow =
2792 IRB.CreateCall(Asm, {AsanShadowGlobal}, ".asan.shadow");
2793 } else {
2794 LocalDynamicShadow =
2795 IRB.CreatePointerCast(AsanShadowGlobal, IntptrTy, ".asan.shadow");
2796 }
2797 } else {
2798 Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
2800 LocalDynamicShadow = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
2801 }
2802 return true;
2803}
2804
2805void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
2806 // Find the one possible call to llvm.localescape and pre-mark allocas passed
2807 // to it as uninteresting. This assumes we haven't started processing allocas
2808 // yet. This check is done up front because iterating the use list in
2809 // isInterestingAlloca would be algorithmically slower.
2810 assert(ProcessedAllocas.empty() && "must process localescape before allocas");
2811
2812 // Try to get the declaration of llvm.localescape. If it's not in the module,
2813 // we can exit early.
2814 if (!F.getParent()->getFunction("llvm.localescape")) return;
2815
2816 // Look for a call to llvm.localescape call in the entry block. It can't be in
2817 // any other block.
2818 for (Instruction &I : F.getEntryBlock()) {
2820 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
2821 // We found a call. Mark all the allocas passed in as uninteresting.
2822 for (Value *Arg : II->args()) {
2823 AllocaInst *AI = dyn_cast<AllocaInst>(Arg->stripPointerCasts());
2824 assert(AI && AI->isStaticAlloca() &&
2825 "non-static alloca arg to localescape");
2826 ProcessedAllocas[AI] = false;
2827 }
2828 break;
2829 }
2830 }
2831}
2832// Mitigation for https://github.com/google/sanitizers/issues/749
2833// We don't instrument Windows catch-block parameters to avoid
2834// interfering with exception handling assumptions.
2835void AddressSanitizer::markCatchParametersAsUninteresting(Function &F) {
2836 for (BasicBlock &BB : F) {
2837 for (Instruction &I : BB) {
2838 if (auto *CatchPad = dyn_cast<CatchPadInst>(&I)) {
2839 // Mark the parameters to a catch-block as uninteresting to avoid
2840 // instrumenting them.
2841 for (Value *Operand : CatchPad->arg_operands())
2842 if (auto *AI = dyn_cast<AllocaInst>(Operand))
2843 ProcessedAllocas[AI] = false;
2844 }
2845 }
2846 }
2847}
2848
2849bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) {
2850 bool ShouldInstrument = Opts.asan_debug_min < 0 || Opts.asan_debug_max < 0 ||
2851 (Instrumented >= Opts.asan_debug_min &&
2852 Instrumented <= Opts.asan_debug_max);
2853 Instrumented++;
2854 return !ShouldInstrument;
2855}
2856
2857bool AddressSanitizer::instrumentFunction(Function &F,
2858 const TargetLibraryInfo *TLI,
2859 const TargetTransformInfo *TTI) {
2860 bool FunctionModified = false;
2861
2862 // Do not apply any instrumentation for naked functions.
2863 if (F.hasFnAttribute(Attribute::Naked))
2864 return FunctionModified;
2865
2866 // If needed, insert __asan_init before checking for SanitizeAddress attr.
2867 // This function needs to be called even if the function body is not
2868 // instrumented.
2869 if (maybeInsertAsanInitAtFunctionEntry(F))
2870 FunctionModified = true;
2871
2872 // Leave if the function doesn't need instrumentation.
2873 if (!F.hasFnAttribute(Attribute::SanitizeAddress)) return FunctionModified;
2874
2875 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2876 return FunctionModified;
2877
2878 LLVM_DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
2879
2880 initializeCallbacks(TLI);
2881
2882 FunctionStateRAII CleanupObj(this);
2883
2884 RuntimeCallInserter RTCI(F);
2885
2886 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(F);
2887
2888 // We can't instrument allocas used with llvm.localescape. Only static allocas
2889 // can be passed to that intrinsic.
2890 markEscapedLocalAllocas(F);
2891
2892 if (TargetTriple.isOSWindows())
2893 markCatchParametersAsUninteresting(F);
2894
2895 // We want to instrument every address only once per basic block (unless there
2896 // are calls between uses).
2897 SmallPtrSet<Value *, 16> TempsToInstrument;
2898 SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
2899 SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
2900 SmallVector<Instruction *, 8> NoReturnCalls;
2902 SmallVector<Instruction *, 16> PointerComparisonsOrSubtracts;
2903
2904 // Fill the set of memory operations to instrument.
2905 for (auto &BB : F) {
2906 AllBlocks.push_back(&BB);
2907 TempsToInstrument.clear();
2908 int NumInsnsPerBB = 0;
2909 for (auto &Inst : BB) {
2910 if (LooksLikeCodeInBug11395(&Inst)) return false;
2911 // Skip instructions inserted by another instrumentation.
2912 if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
2913 continue;
2914 SmallVector<InterestingMemoryOperand, 1> InterestingOperands;
2915 getInterestingMemoryOperands(&Inst, InterestingOperands, TTI);
2916
2917 if (!InterestingOperands.empty()) {
2918 for (auto &Operand : InterestingOperands) {
2919 if (Opts.asan_opt && Opts.asan_opt_same_temp) {
2920 Value *Ptr = Operand.getPtr();
2921 // If we have a mask, skip instrumentation if we've already
2922 // instrumented the full object. But don't add to TempsToInstrument
2923 // because we might get another load/store with a different mask.
2924 if (Operand.MaybeMask) {
2925 if (TempsToInstrument.count(Ptr))
2926 continue; // We've seen this (whole) temp in the current BB.
2927 } else {
2928 if (!TempsToInstrument.insert(Ptr).second)
2929 continue; // We've seen this temp in the current BB.
2930 }
2931 }
2932 OperandsToInstrument.push_back(Operand);
2933 NumInsnsPerBB++;
2934 }
2935 } else if (((Opts.asan_detect_invalid_pointer_pair ||
2936 Opts.asan_detect_invalid_pointer_cmp) &&
2938 ((Opts.asan_detect_invalid_pointer_pair ||
2939 Opts.asan_detect_invalid_pointer_sub) &&
2941 PointerComparisonsOrSubtracts.push_back(&Inst);
2942 } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst)) {
2943 // ok, take it.
2944 IntrinToInstrument.push_back(MI);
2945 NumInsnsPerBB++;
2946 } else {
2947 if (auto *CB = dyn_cast<CallBase>(&Inst)) {
2948 // A call inside BB.
2949 TempsToInstrument.clear();
2950 if (CB->doesNotReturn())
2951 NoReturnCalls.push_back(CB);
2952 }
2953 if (CallInst *CI = dyn_cast<CallInst>(&Inst))
2955 }
2956 if (NumInsnsPerBB >= Opts.asan_max_ins_per_bb)
2957 break;
2958 }
2959 }
2960
2961 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
2962 OperandsToInstrument.size() + IntrinToInstrument.size() >
2963 (unsigned)InstrumentationWithCallsThreshold);
2964 const DataLayout &DL = F.getDataLayout();
2965 ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext());
2966
2967 // Instrument.
2968 int NumInstrumented = 0;
2969 for (auto &Operand : OperandsToInstrument) {
2970 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2971 instrumentMop(ObjSizeVis, Operand, UseCalls,
2972 F.getDataLayout(), RTCI);
2973 FunctionModified = true;
2974 }
2975 for (auto *Inst : IntrinToInstrument) {
2976 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2977 instrumentMemIntrinsic(Inst, RTCI);
2978 FunctionModified = true;
2979 }
2980
2981 FunctionStackPoisoner FSP(F, *this, RTCI);
2982 bool ChangedStack = FSP.runOnFunction();
2983
2984 // We must unpoison the stack before NoReturn calls (throw, _exit, etc).
2985 // See e.g. https://github.com/google/sanitizers/issues/37
2986 for (auto *CI : NoReturnCalls) {
2987 IRBuilder<> IRB(CI);
2988 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
2989 }
2990
2991 for (auto *Inst : PointerComparisonsOrSubtracts) {
2992 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
2993 }
2994
2995 if (ChangedStack || !NoReturnCalls.empty())
2996 FunctionModified = true;
2997
2998 LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " "
2999 << F << "\n");
3000
3001 return FunctionModified;
3002}
3003
3004// Workaround for bug 11395: we don't want to instrument stack in functions
3005// with large assembly blobs (32-bit only), otherwise reg alloc may crash.
3006// FIXME: remove once the bug 11395 is fixed.
3007bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) {
3008 if (LongSize != 32) return false;
3010 if (!CI || !CI->isInlineAsm()) return false;
3011 if (CI->arg_size() <= 5)
3012 return false;
3013 // We have inline assembly with quite a few arguments.
3014 return true;
3015}
3016
3017void FunctionStackPoisoner::initializeCallbacks(Module &M) {
3018 IRBuilder<> IRB(M);
3019 if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always ||
3020 ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
3021 const char *MallocNameTemplate =
3022 ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always
3025 for (int Index = 0; Index <= kMaxAsanStackMallocSizeClass; Index++) {
3026 std::string Suffix = itostr(Index);
3027 AsanStackMallocFunc[Index] = ASan.Inserter.insertFunction(
3028 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3029 AsanStackFreeFunc[Index] =
3030 ASan.Inserter.insertFunction(kAsanStackFreeNameTemplate + Suffix,
3031 IRB.getVoidTy(), IntptrTy, IntptrTy);
3032 }
3033 }
3034 if (ASan.UseAfterScope) {
3035 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3036 kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
3037 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3038 kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
3039 }
3040
3041 for (size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3042 0xf3, 0xf5, 0xf8}) {
3043 std::ostringstream Name;
3045 Name << std::setw(2) << std::setfill('0') << std::hex << Val;
3046 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3047 Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy);
3048 }
3049
3050 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3051 kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
3052 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3053 kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
3054}
3055
3056void FunctionStackPoisoner::copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
3057 ArrayRef<uint8_t> ShadowBytes,
3058 size_t Begin, size_t End,
3059 IRBuilder<> &IRB,
3060 Value *ShadowBase) {
3061 if (Begin >= End)
3062 return;
3063
3064 const size_t LargestStoreSizeInBytes =
3065 std::min<size_t>(sizeof(uint64_t), ASan.LongSize / 8);
3066
3067 const bool IsLittleEndian = F.getDataLayout().isLittleEndian();
3068
3069 // Poison given range in shadow using larges store size with out leading and
3070 // trailing zeros in ShadowMask. Zeros never change, so they need neither
3071 // poisoning nor up-poisoning. Still we don't mind if some of them get into a
3072 // middle of a store.
3073 for (size_t i = Begin; i < End;) {
3074 if (!ShadowMask[i]) {
3075 assert(!ShadowBytes[i]);
3076 ++i;
3077 continue;
3078 }
3079
3080 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3081 // Fit store size into the range.
3082 while (StoreSizeInBytes > End - i)
3083 StoreSizeInBytes /= 2;
3084
3085 // Minimize store size by trimming trailing zeros.
3086 for (size_t j = StoreSizeInBytes - 1; j && !ShadowMask[i + j]; --j) {
3087 while (j <= StoreSizeInBytes / 2)
3088 StoreSizeInBytes /= 2;
3089 }
3090
3091 uint64_t Val = 0;
3092 for (size_t j = 0; j < StoreSizeInBytes; j++) {
3093 if (IsLittleEndian)
3094 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
3095 else
3096 Val = (Val << 8) | ShadowBytes[i + j];
3097 }
3098
3099 Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3100 Value *Poison = IRB.getIntN(StoreSizeInBytes * 8, Val);
3102 Poison, IRB.CreateIntToPtr(Ptr, PointerType::getUnqual(Poison->getContext())),
3103 Align(1));
3104
3105 i += StoreSizeInBytes;
3106 }
3107}
3108
3109void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
3110 ArrayRef<uint8_t> ShadowBytes,
3111 IRBuilder<> &IRB, Value *ShadowBase) {
3112 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.size(), IRB, ShadowBase);
3113}
3114
3115void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
3116 ArrayRef<uint8_t> ShadowBytes,
3117 size_t Begin, size_t End,
3118 IRBuilder<> &IRB, Value *ShadowBase) {
3119 assert(ShadowMask.size() == ShadowBytes.size());
3120 size_t Done = Begin;
3121 for (size_t i = Begin, j = Begin + 1; i < End; i = j++) {
3122 if (!ShadowMask[i]) {
3123 assert(!ShadowBytes[i]);
3124 continue;
3125 }
3126 uint8_t Val = ShadowBytes[i];
3127 if (!AsanSetShadowFunc[Val])
3128 continue;
3129
3130 // Skip same values.
3131 for (; j < End && ShadowMask[j] && Val == ShadowBytes[j]; ++j) {
3132 }
3133
3134 if (j - i >= ASan.MaxInlinePoisoningSize) {
3135 copyToShadowInline(ShadowMask, ShadowBytes, Done, i, IRB, ShadowBase);
3136 RTCI.createRuntimeCall(
3137 IRB, AsanSetShadowFunc[Val],
3138 {IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3139 ConstantInt::get(IntptrTy, j - i)});
3140 Done = j;
3141 }
3142 }
3143
3144 copyToShadowInline(ShadowMask, ShadowBytes, Done, End, IRB, ShadowBase);
3145}
3146
3147// Fake stack allocator (asan_fake_stack.h) has 11 size classes
3148// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass
3149static int StackMallocSizeClass(uint64_t LocalStackSize) {
3150 assert(LocalStackSize <= kMaxStackMallocSize);
3151 uint64_t MaxSize = kMinStackMallocSize;
3152 for (int i = 0;; i++, MaxSize *= 2)
3153 if (LocalStackSize <= MaxSize) return i;
3154 llvm_unreachable("impossible LocalStackSize");
3155}
3156
3157void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3158 Instruction *CopyInsertPoint = &F.front().front();
3159 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3160 // Insert after the dynamic shadow location is determined
3161 CopyInsertPoint = CopyInsertPoint->getNextNode();
3162 assert(CopyInsertPoint);
3163 }
3164 IRBuilder<> IRB(CopyInsertPoint);
3165 const DataLayout &DL = F.getDataLayout();
3166 for (Argument &Arg : F.args()) {
3167 if (Arg.hasByValAttr()) {
3168 Type *Ty = Arg.getParamByValType();
3169 const Align Alignment =
3170 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3171
3172 AllocaInst *AI = IRB.CreateAlloca(
3173 Ty, nullptr,
3174 (Arg.hasName() ? Arg.getName() : "Arg" + Twine(Arg.getArgNo())) +
3175 ".byval");
3176 AI->setAlignment(Alignment);
3177 Arg.replaceAllUsesWith(AI);
3178
3179 uint64_t AllocSize = DL.getTypeAllocSize(Ty);
3180 IRB.CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3181 }
3182 }
3183}
3184
3185PHINode *FunctionStackPoisoner::createPHI(IRBuilder<> &IRB, Value *Cond,
3186 Value *ValueIfTrue,
3187 Instruction *ThenTerm,
3188 Value *ValueIfFalse) {
3189 PHINode *PHI = IRB.CreatePHI(ValueIfTrue->getType(), 2);
3190 BasicBlock *CondBlock = cast<Instruction>(Cond)->getParent();
3191 PHI->addIncoming(ValueIfFalse, CondBlock);
3192 BasicBlock *ThenBlock = ThenTerm->getParent();
3193 PHI->addIncoming(ValueIfTrue, ThenBlock);
3194 return PHI;
3195}
3196
3197Value *FunctionStackPoisoner::createAllocaForLayout(
3198 IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) {
3199 AllocaInst *Alloca;
3200 if (Dynamic) {
3201 Alloca = IRB.CreateAlloca(IRB.getInt8Ty(),
3202 ConstantInt::get(IRB.getInt64Ty(), L.FrameSize),
3203 "MyAlloca");
3204 } else {
3205 Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize),
3206 nullptr, "MyAlloca");
3207 assert(Alloca->isStaticAlloca());
3208 }
3209 assert((Opts.asan_realign_stack & (Opts.asan_realign_stack - 1)) == 0);
3210 uint64_t FrameAlignment =
3211 std::max(L.FrameAlignment, uint64_t(Opts.asan_realign_stack));
3212 Alloca->setAlignment(Align(FrameAlignment));
3213 return Alloca;
3214}
3215
3216void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3217 BasicBlock &FirstBB = *F.begin();
3218 IRBuilder<> IRB(dyn_cast<Instruction>(FirstBB.begin()));
3219 DynamicAllocaLayout = IRB.CreateAlloca(IntptrTy, nullptr);
3220 IRB.CreateStore(Constant::getNullValue(IntptrTy), DynamicAllocaLayout);
3221 DynamicAllocaLayout->setAlignment(Align(32));
3222}
3223
3224void FunctionStackPoisoner::processDynamicAllocas() {
3225 if (!Opts.asan_instrument_dynamic_allocas || DynamicAllocaVec.empty()) {
3226 assert(DynamicAllocaPoisonCallVec.empty());
3227 return;
3228 }
3229
3230 // Insert poison calls for lifetime intrinsics for dynamic allocas.
3231 for (const auto &APC : DynamicAllocaPoisonCallVec) {
3232 assert(APC.InsBefore);
3233 assert(APC.AI);
3234 assert(ASan.isInterestingAlloca(*APC.AI));
3235 assert(!APC.AI->isStaticAlloca());
3236
3237 IRBuilder<> IRB(APC.InsBefore);
3238 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3239 // Dynamic allocas will be unpoisoned unconditionally below in
3240 // unpoisonDynamicAllocas.
3241 // Flag that we need unpoison static allocas.
3242 }
3243
3244 // Handle dynamic allocas.
3245 createDynamicAllocasInitStorage();
3246 for (auto &AI : DynamicAllocaVec)
3247 handleDynamicAllocaCall(AI);
3248 unpoisonDynamicAllocas();
3249}
3250
3251/// Collect instructions in the entry block after \p InsBefore which initialize
3252/// permanent storage for a function argument. These instructions must remain in
3253/// the entry block so that uninitialized values do not appear in backtraces. An
3254/// added benefit is that this conserves spill slots. This does not move stores
3255/// before instrumented / "interesting" allocas.
3257 AddressSanitizer &ASan, Instruction &InsBefore,
3258 SmallVectorImpl<Instruction *> &InitInsts) {
3259 Instruction *Start = InsBefore.getNextNode();
3260 for (Instruction *It = Start; It; It = It->getNextNode()) {
3261 // Argument initialization looks like:
3262 // 1) store <Argument>, <Alloca> OR
3263 // 2) <CastArgument> = cast <Argument> to ...
3264 // store <CastArgument> to <Alloca>
3265 // Do not consider any other kind of instruction.
3266 //
3267 // Note: This covers all known cases, but may not be exhaustive. An
3268 // alternative to pattern-matching stores is to DFS over all Argument uses:
3269 // this might be more general, but is probably much more complicated.
3270 if (isa<AllocaInst>(It) || isa<CastInst>(It))
3271 continue;
3272 if (auto *Store = dyn_cast<StoreInst>(It)) {
3273 // The store destination must be an alloca that isn't interesting for
3274 // ASan to instrument. These are moved up before InsBefore, and they're
3275 // not interesting because allocas for arguments can be mem2reg'd.
3276 auto *Alloca = dyn_cast<AllocaInst>(Store->getPointerOperand());
3277 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3278 continue;
3279
3280 Value *Val = Store->getValueOperand();
3281 bool IsDirectArgInit = isa<Argument>(Val);
3282 bool IsArgInitViaCast =
3283 isa<CastInst>(Val) &&
3284 isa<Argument>(cast<CastInst>(Val)->getOperand(0)) &&
3285 // Check that the cast appears directly before the store. Otherwise
3286 // moving the cast before InsBefore may break the IR.
3287 Val == It->getPrevNode();
3288 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3289 if (!IsArgInit)
3290 continue;
3291
3292 if (IsArgInitViaCast)
3293 InitInsts.push_back(cast<Instruction>(Val));
3294 InitInsts.push_back(Store);
3295 continue;
3296 }
3297
3298 // Do not reorder past unknown instructions: argument initialization should
3299 // only involve casts and stores.
3300 return;
3301 }
3302}
3303
3305 // Alloca could have been renamed for uniqueness. Its true name will have been
3306 // recorded as an annotation.
3307 if (AI->hasMetadata(LLVMContext::MD_annotation)) {
3308 MDTuple *AllocaAnnotations =
3309 cast<MDTuple>(AI->getMetadata(LLVMContext::MD_annotation));
3310 for (auto &Annotation : AllocaAnnotations->operands()) {
3311 if (!isa<MDTuple>(Annotation))
3312 continue;
3313 auto AnnotationTuple = cast<MDTuple>(Annotation);
3314 for (unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3315 Index++) {
3316 // All annotations are strings
3317 auto MetadataString =
3318 cast<MDString>(AnnotationTuple->getOperand(Index));
3319 if (MetadataString->getString() == "alloca_name_altered")
3320 return cast<MDString>(AnnotationTuple->getOperand(Index + 1))
3321 ->getString();
3322 }
3323 }
3324 }
3325 return AI->getName();
3326}
3327
3328void FunctionStackPoisoner::processStaticAllocas() {
3329 if (AllocaVec.empty()) {
3330 assert(StaticAllocaPoisonCallVec.empty());
3331 return;
3332 }
3333
3334 int StackMallocIdx = -1;
3335 DebugLoc EntryDebugLocation;
3336 if (auto SP = F.getSubprogram())
3337 EntryDebugLocation =
3338 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
3339
3340 Instruction *InsBefore = AllocaVec[0];
3341 IRBuilder<> IRB(InsBefore);
3342
3343 // Make sure non-instrumented allocas stay in the entry block. Otherwise,
3344 // debug info is broken, because only entry-block allocas are treated as
3345 // regular stack slots.
3346 auto InsBeforeB = InsBefore->getParent();
3347 assert(InsBeforeB == &F.getEntryBlock());
3348 for (auto *AI : StaticAllocasToMoveUp)
3349 if (AI->getParent() == InsBeforeB)
3350 AI->moveBefore(InsBefore->getIterator());
3351
3352 // Move stores of arguments into entry-block allocas as well. This prevents
3353 // extra stack slots from being generated (to house the argument values until
3354 // they can be stored into the allocas). This also prevents uninitialized
3355 // values from being shown in backtraces.
3356 SmallVector<Instruction *, 8> ArgInitInsts;
3357 findStoresToUninstrumentedArgAllocas(ASan, *InsBefore, ArgInitInsts);
3358 for (Instruction *ArgInitInst : ArgInitInsts)
3359 ArgInitInst->moveBefore(InsBefore->getIterator());
3360
3361 // If we have a call to llvm.localescape, keep it in the entry block.
3362 if (LocalEscapeCall)
3363 LocalEscapeCall->moveBefore(InsBefore->getIterator());
3364
3366 SVD.reserve(AllocaVec.size());
3367 for (AllocaInst *AI : AllocaVec) {
3370 ASan.getAllocaSizeInBytes(*AI),
3371 0,
3372 AI->getAlign().value(),
3373 AI,
3374 0,
3375 0};
3376 SVD.push_back(D);
3377 }
3378
3379 // Minimal header size (left redzone) is 4 pointers,
3380 // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms.
3381 uint64_t Granularity = 1ULL << Mapping.Scale;
3382 uint64_t MinHeaderSize = std::max((uint64_t)ASan.LongSize / 2, Granularity);
3383 const ASanStackFrameLayout &L =
3384 ComputeASanStackFrameLayout(SVD, Granularity, MinHeaderSize);
3385
3386 // Build AllocaToSVDMap for ASanStackVariableDescription lookup.
3388 for (auto &Desc : SVD)
3389 AllocaToSVDMap[Desc.AI] = &Desc;
3390
3391 // Update SVD with information from lifetime intrinsics.
3392 for (const auto &APC : StaticAllocaPoisonCallVec) {
3393 assert(APC.InsBefore);
3394 assert(APC.AI);
3395 assert(ASan.isInterestingAlloca(*APC.AI));
3396 assert(APC.AI->isStaticAlloca());
3397
3398 ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI];
3399 Desc.LifetimeSize = Desc.Size;
3400 if (const DILocation *FnLoc = EntryDebugLocation.get()) {
3401 if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3402 if (LifetimeLoc->getFile() == FnLoc->getFile())
3403 if (unsigned Line = LifetimeLoc->getLine())
3404 Desc.Line = std::min(Desc.Line ? Desc.Line : Line, Line);
3405 }
3406 }
3407 }
3408
3409 auto DescriptionString = ComputeASanStackFrameDescription(SVD);
3410 LLVM_DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n");
3411 uint64_t LocalStackSize = L.FrameSize;
3412 bool DoStackMalloc =
3413 ASan.UseAfterReturn != AsanDetectStackUseAfterReturnMode::Never &&
3414 !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize;
3415 bool DoDynamicAlloca = Opts.asan_stack_dynamic_alloca;
3416 // Don't do dynamic alloca or stack malloc if:
3417 // 1) There is inline asm: too often it makes assumptions on which registers
3418 // are available.
3419 // 2) There is a returns_twice call (typically setjmp), which is
3420 // optimization-hostile, and doesn't play well with introduced indirect
3421 // register-relative calculation of local variable addresses.
3422 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3423 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3424
3425 Type *PtrTy = F.getDataLayout().getAllocaPtrType(F.getContext());
3426 Value *StaticAlloca =
3427 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false);
3428
3429 Value *FakeStackPtr;
3430 Value *FakeStackInt;
3431 Value *LocalStackBase;
3432 Value *LocalStackBaseAlloca;
3433 uint8_t DIExprFlags = DIExpression::ApplyOffset;
3434
3435 if (DoStackMalloc) {
3436 LocalStackBaseAlloca =
3437 IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base");
3438 if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
3439 // void *FakeStack = __asan_option_detect_stack_use_after_return
3440 // ? __asan_stack_malloc_N(LocalStackSize)
3441 // : nullptr;
3442 // void *LocalStackBase = (FakeStack) ? FakeStack :
3443 // alloca(LocalStackSize);
3444 Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal(
3446 Value *UseAfterReturnIsEnabled = IRB.CreateICmpNE(
3447 IRB.CreateLoad(IRB.getInt32Ty(), OptionDetectUseAfterReturn),
3449 Instruction *Term =
3450 SplitBlockAndInsertIfThen(UseAfterReturnIsEnabled, InsBefore, false);
3451 IRBuilder<> IRBIf(Term);
3452 StackMallocIdx = StackMallocSizeClass(LocalStackSize);
3453 assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass);
3454 Value *FakeStackValue =
3455 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3456 ConstantInt::get(IntptrTy, LocalStackSize));
3457 IRB.SetInsertPoint(InsBefore);
3458 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3459 Term, ConstantInt::get(IntptrTy, 0));
3460 } else {
3461 // assert(ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode:Always)
3462 // void *FakeStack = __asan_stack_malloc_N(LocalStackSize);
3463 // void *LocalStackBase = (FakeStack) ? FakeStack :
3464 // alloca(LocalStackSize);
3465 StackMallocIdx = StackMallocSizeClass(LocalStackSize);
3466 FakeStackInt =
3467 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3468 ConstantInt::get(IntptrTy, LocalStackSize));
3469 }
3470 FakeStackPtr = IRB.CreateIntToPtr(FakeStackInt, PtrTy);
3471 Value *NoFakeStack =
3472 IRB.CreateICmpEQ(FakeStackInt, Constant::getNullValue(IntptrTy));
3473 Instruction *Term =
3474 SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false);
3475 IRBuilder<> IRBIf(Term);
3476 Value *AllocaValue =
3477 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca;
3478
3479 IRB.SetInsertPoint(InsBefore);
3480 LocalStackBase =
3481 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3482 IRB.CreateStore(LocalStackBase, LocalStackBaseAlloca);
3483 DIExprFlags |= DIExpression::DerefBefore;
3484 } else {
3485 // void *FakeStack = nullptr;
3486 // void *LocalStackBase = alloca(LocalStackSize);
3487 FakeStackInt = Constant::getNullValue(IntptrTy);
3488 FakeStackPtr = Constant::getNullValue(PtrTy);
3489 LocalStackBase =
3490 DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca;
3491 LocalStackBaseAlloca = LocalStackBase;
3492 }
3493
3494 // Replace Alloca instructions with base+offset.
3495 SmallVector<Value *> NewAllocaPtrs;
3496 for (const auto &Desc : SVD) {
3497 AllocaInst *AI = Desc.AI;
3498 replaceDbgDeclare(AI, LocalStackBaseAlloca, DIB, DIExprFlags, Desc.Offset);
3499 Value *NewAllocaPtr = IRB.CreatePtrAdd(
3500 LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset));
3501 if (NewAllocaPtr->getType() != AI->getType())
3502 NewAllocaPtr = IRB.CreateAddrSpaceCast(NewAllocaPtr, AI->getType());
3503 AI->replaceAllUsesWith(NewAllocaPtr);
3504 NewAllocaPtrs.push_back(NewAllocaPtr);
3505 }
3506
3507 // The left-most redzone has enough space for at least 4 pointers.
3508 // Write the Magic value to redzone[0].
3509 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic),
3510 LocalStackBase);
3511 // Write the frame description constant to redzone[1].
3512 Value *BasePlus1 = IRB.CreatePtrAdd(
3513 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3514 GlobalVariable *StackDescriptionGlobal =
3515 createPrivateGlobalForString(*F.getParent(), DescriptionString,
3516 /*AllowMerging*/ true, genName("stack"));
3517 Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy);
3518 IRB.CreateStore(Description, BasePlus1);
3519 // Write the PC to redzone[2].
3520 Value *BasePlus2 = IRB.CreatePtrAdd(
3521 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3522 IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2);
3523
3524 const auto &ShadowAfterScope = GetShadowBytesAfterScope(SVD, L);
3525
3526 // Poison the stack red zones at the entry.
3527 Value *ShadowBase =
3528 ASan.memToShadow(IRB.CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3529 // As mask we must use most poisoned case: red zones and after scope.
3530 // As bytes we can use either the same or just red zones only.
3531 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3532
3533 if (!StaticAllocaPoisonCallVec.empty()) {
3534 const auto &ShadowInScope = GetShadowBytes(SVD, L);
3535
3536 // Poison static allocas near lifetime intrinsics.
3537 for (const auto &APC : StaticAllocaPoisonCallVec) {
3538 const ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI];
3539 assert(Desc.Offset % L.Granularity == 0);
3540 size_t Begin = Desc.Offset / L.Granularity;
3541 size_t End = Begin + (APC.Size + L.Granularity - 1) / L.Granularity;
3542
3543 IRBuilder<> IRB(APC.InsBefore);
3544 copyToShadow(ShadowAfterScope,
3545 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3546 IRB, ShadowBase);
3547 }
3548 }
3549
3550 // Remove lifetime markers now that these are no longer allocas.
3551 for (Value *NewAllocaPtr : NewAllocaPtrs) {
3552 for (User *U : make_early_inc_range(NewAllocaPtr->users())) {
3553 auto *I = cast<Instruction>(U);
3554 if (I->isLifetimeStartOrEnd())
3555 I->eraseFromParent();
3556 }
3557 }
3558
3559 SmallVector<uint8_t, 64> ShadowClean(ShadowAfterScope.size(), 0);
3560 SmallVector<uint8_t, 64> ShadowAfterReturn;
3561
3562 // (Un)poison the stack before all ret instructions.
3563 for (Instruction *Ret : RetVec) {
3564 IRBuilder<> IRBRet(Ret);
3565 // Mark the current frame as retired.
3566 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),
3567 LocalStackBase);
3568 if (DoStackMalloc) {
3569 assert(StackMallocIdx >= 0);
3570 // if FakeStack != 0 // LocalStackBase == FakeStack
3571 // // In use-after-return mode, poison the whole stack frame.
3572 // if StackMallocIdx <= 4
3573 // // For small sizes inline the whole thing:
3574 // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
3575 // **SavedFlagPtr(FakeStack) = 0
3576 // else
3577 // __asan_stack_free_N(FakeStack, LocalStackSize)
3578 // else
3579 // <This is not a fake stack; unpoison the redzones>
3580 Value *Cmp =
3581 IRBRet.CreateICmpNE(FakeStackInt, Constant::getNullValue(IntptrTy));
3582 Instruction *ThenTerm, *ElseTerm;
3583 SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm);
3584
3585 IRBuilder<> IRBPoison(ThenTerm);
3586 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3587 int ClassSize = kMinStackMallocSize << StackMallocIdx;
3588 ShadowAfterReturn.resize(ClassSize / L.Granularity,
3590 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3591 ShadowBase);
3592 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3593 FakeStackPtr,
3594 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3595 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3596 IRBPoison.CreateStore(
3597 Constant::getNullValue(IRBPoison.getInt8Ty()),
3598 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3599 } else {
3600 // For larger frames call __asan_stack_free_*.
3601 RTCI.createRuntimeCall(
3602 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3603 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3604 }
3605
3606 IRBuilder<> IRBElse(ElseTerm);
3607 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3608 } else {
3609 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3610 }
3611 }
3612
3613 // We are done. Remove the old unused alloca instructions.
3614 for (auto *AI : AllocaVec)
3615 AI->eraseFromParent();
3616}
3617
3618void FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size,
3619 IRBuilder<> &IRB, bool DoPoison) {
3620 // For now just insert the call to ASan runtime.
3621 Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy);
3622 Value *SizeArg = ConstantInt::get(IntptrTy, Size);
3623 RTCI.createRuntimeCall(
3624 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3625 {AddrArg, SizeArg});
3626}
3627
3628// Handling llvm.lifetime intrinsics for a given %alloca:
3629// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca.
3630// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect
3631// invalid accesses) and unpoison it for llvm.lifetime.start (the memory
3632// could be poisoned by previous llvm.lifetime.end instruction, as the
3633// variable may go in and out of scope several times, e.g. in loops).
3634// (3) if we poisoned at least one %alloca in a function,
3635// unpoison the whole stack frame at function exit.
3636void FunctionStackPoisoner::handleDynamicAllocaCall(AllocaInst *AI) {
3637 IRBuilder<> IRB(AI);
3638
3639 const Align Alignment = std::max(Align(kAllocaRzSize), AI->getAlign());
3640 const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1;
3641
3642 Value *Zero = Constant::getNullValue(IntptrTy);
3643 Value *AllocaRzSize = ConstantInt::get(IntptrTy, kAllocaRzSize);
3644 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3645
3646 // Since we need to extend alloca with additional memory to locate
3647 // redzones, and OldSize is number of allocated blocks with
3648 // ElementSize size, get allocated memory size in bytes by
3649 // OldSize * ElementSize.
3650 Value *OldSize = IRB.CreateAllocationSize(IntptrTy, AI);
3651
3652 // PartialSize = OldSize % 32
3653 Value *PartialSize = IRB.CreateAnd(OldSize, AllocaRzMask);
3654
3655 // Misalign = kAllocaRzSize - PartialSize;
3656 Value *Misalign = IRB.CreateSub(AllocaRzSize, PartialSize);
3657
3658 // PartialPadding = Misalign != kAllocaRzSize ? Misalign : 0;
3659 Value *Cond = IRB.CreateICmpNE(Misalign, AllocaRzSize);
3660 Value *PartialPadding = IRB.CreateSelect(Cond, Misalign, Zero);
3661
3662 // AdditionalChunkSize = Alignment + PartialPadding + kAllocaRzSize
3663 // Alignment is added to locate left redzone, PartialPadding for possible
3664 // partial redzone and kAllocaRzSize for right redzone respectively.
3665 Value *AdditionalChunkSize = IRB.CreateAdd(
3666 ConstantInt::get(IntptrTy, Alignment.value() + kAllocaRzSize),
3667 PartialPadding);
3668
3669 Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize);
3670
3671 // Insert new alloca with new NewSize and Alignment params.
3672 AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize);
3673 NewAlloca->setAlignment(Alignment);
3674
3675 // NewAddress = Address + Alignment
3676 Value *NewAddress =
3677 IRB.CreateAdd(IRB.CreatePtrToInt(NewAlloca, IntptrTy),
3678 ConstantInt::get(IntptrTy, Alignment.value()));
3679
3680 // Insert __asan_alloca_poison call for new created alloca.
3681 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3682
3683 // Store the last alloca's address to DynamicAllocaLayout. We'll need this
3684 // for unpoisoning stuff.
3685 IRB.CreateStore(IRB.CreatePtrToInt(NewAlloca, IntptrTy), DynamicAllocaLayout);
3686
3687 Value *NewAddressPtr = IRB.CreateIntToPtr(NewAddress, AI->getType());
3688
3689 // Remove lifetime markers now that this is no longer an alloca.
3690 for (User *U : make_early_inc_range(AI->users())) {
3691 auto *I = cast<Instruction>(U);
3692 if (I->isLifetimeStartOrEnd())
3693 I->eraseFromParent();
3694 }
3695
3696 // Replace all uses of AddressReturnedByAlloca with NewAddressPtr.
3697 AI->replaceAllUsesWith(NewAddressPtr);
3698
3699 // We are done. Erase old alloca from parent.
3700 AI->eraseFromParent();
3701}
3702
3703// isSafeAccess returns true if Addr is always inbounds with respect to its
3704// base object. For example, it is a field access or an array access with
3705// constant inbounds index.
3706bool AddressSanitizer::isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
3707 Value *Addr, TypeSize TypeStoreSize) const {
3708 if (TypeStoreSize.isScalable())
3709 // TODO: We can use vscale_range to convert a scalable value to an
3710 // upper bound on the access size.
3711 return false;
3712
3713 SizeOffsetAPInt SizeOffset = ObjSizeVis.compute(Addr);
3714 if (!SizeOffset.bothKnown())
3715 return false;
3716
3717 uint64_t Size = SizeOffset.Size.getZExtValue();
3718 int64_t Offset = SizeOffset.Offset.getSExtValue();
3719
3720 // Three checks are required to ensure safety:
3721 // . Offset >= 0 (since the offset is given from the base ptr)
3722 // . Size >= Offset (unsigned)
3723 // . Size - Offset >= NeededSize (unsigned)
3724 return Offset >= 0 && Size >= uint64_t(Offset) &&
3725 Size - uint64_t(Offset) >= TypeStoreSize / 8;
3726}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void findStoresToUninstrumentedArgAllocas(AddressSanitizer &ASan, Instruction &InsBefore, SmallVectorImpl< Instruction * > &InitInsts)
Collect instructions in the entry block after InsBefore which initialize permanent storage for a func...
static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I, Instruction *InsertBefore, Value *Addr, MaybeAlign Alignment, unsigned Granularity, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp, RuntimeCallInserter &RTCI)
static const uint64_t kDefaultShadowScale
const char kAMDGPUUnreachableName[]
constexpr size_t kAccessSizeIndexMask
static const uint64_t kPS_ShadowOffset64
static const uint64_t kFreeBSD_ShadowOffset32
constexpr size_t kIsWriteShift
static const uint64_t kSmallX86_64ShadowOffsetAlignMask
static bool isInterestingPointerSubtraction(Instruction *I)
const char kAMDGPUAddressSharedName[]
const char kAsanStackFreeNameTemplate[]
constexpr size_t kCompileKernelMask
const char kAsanOptionDetectUseAfterReturn[]
static const uint64_t kRISCV64_ShadowOffset64
const char kAsanSetShadowPrefix[]
static Twine genName(StringRef suffix)
const char kAsanPtrCmp[]
static uint64_t GetCtorAndDtorPriority(Triple &TargetTriple)
const char kAsanStackMallocNameTemplate[]
const char kAsanInitName[]
static bool isPointerPairOperand(Value *V, Type *IntptrTy)
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static const uint64_t kFreeBSD_ShadowOffset64
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
constexpr size_t kAccessSizeIndexShift
const char kAsanPoisonStackMemoryName[]
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static ShadowMapping getShadowMapping(const InstrumentationOptions &Opts, const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static const uintptr_t kCurrentStackFrameMagic
static const uint64_t kPPC64_ShadowOffset64
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static const uint64_t kNetBSD_ShadowOffset64
const char kAsanPtrSub[]
static bool isSupportedAddrspace(const InstrumentationOptions &Opts, const Triple &TargetTriple, Value *Addr)
static const uint64_t kWindowsShadowOffset32
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
const char kAsanReportErrorTemplate[]
static StringRef getAllocaName(AllocaInst *AI)
static const uintptr_t kRetiredStackFrameMagic
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool isPointerOperand(Value *I, User *U)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Finalize Linkage
dxil translate DXIL Translate Metadata
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
This defines the Use class.
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition Lint.cpp:540
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:629
Machine Check Debug Module
This file contains the declarations for metadata subclasses.
uint64_t IntrinsicInst * II
#define P(N)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
if(PassOpts->AAPipeline)
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
#define OP(OPC)
Definition Instruction.h:46
This file defines the SmallPtrSet class.
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
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
LLVM_ABI AddressSanitizerPass(const AddressSanitizerOptions &Options, bool UseGlobalGC=true, bool UseOdrIndicator=true, AsanDtorKind DestructorKind=AsanDtorKind::Global, AsanCtorKind ConstructorKind=AsanCtorKind::Global)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
bool isScalable() const
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Class to represent array types.
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
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:446
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
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
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
bool isInlineAsm() const
Check if this call is an inline asm statement.
void setCannotMerge()
static LLVM_ABI CallBase * addOperandBundle(CallBase *CB, uint32_t ID, OperandBundleDef OB, InsertPosition InsertPt=nullptr)
Create a clone of CB with operand bundle OB added.
bool doesNotReturn() const
Determine if the call cannot return.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
@ Largest
The linker will choose the largest COMDAT.
Definition Comdat.h:39
@ SameSize
The data referenced by the COMDAT must be the same size.
Definition Comdat.h:41
@ Any
The linker may choose any COMDAT.
Definition Comdat.h:37
@ NoDeduplicate
No deduplication is performed.
Definition Comdat.h:40
@ ExactMatch
The data referenced by the COMDAT must be the same.
Definition Comdat.h:38
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
ConstantArray - Constant Array Declarations.
Definition Constants.h:590
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI bool isValueValidForType(Type *Ty, uint64_t V)
This static method returns true if the type Ty is big enough to represent the value V.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
DILocation * get() const
Get the underlying DILocation.
Definition DebugLoc.h:226
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
const BasicBlock & front() const
Definition Function.h:845
DISubprogram * getSubprogram() const
Get the attached subprogram.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
Definition Function.cpp:376
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition Function.h:890
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
const Constant * getAliasee() const
Definition GlobalAlias.h:87
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
LLVM_ABI void copyMetadata(const GlobalObject *Src, unsigned Offset)
Copy metadata from Src, adjusting offsets by Offset.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
Definition Globals.cpp:348
VisibilityTypes getVisibility() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
ThreadLocalMode getThreadLocalMode() const
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ CommonLinkage
Tentative definitions.
Definition GlobalValue.h:63
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
DLLStorageClassTypes getDLLStorageClass() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
Definition Globals.cpp:647
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNull=false)
Definition IRBuilder.h:2257
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1889
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:516
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2666
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1943
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Definition IRBuilder.h:660
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2306
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2419
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:180
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
BasicBlock * GetInsertBlock() const
Definition IRBuilder.h:179
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:536
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2395
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2020
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:474
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2556
Value * CreateNot(Value *V, const Twine &Name="")
Definition IRBuilder.h:1859
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2391
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1444
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
Definition IRBuilder.h:484
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 * 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
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2242
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition IRBuilder.h:2772
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2570
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
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
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:569
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1962
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1597
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:521
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1461
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
Base class for instruction visitors.
Definition InstVisitor.h:78
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
iterator_range< user_iterator > users()
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
A wrapper class for inspecting calls to intrinsic functions.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
An instruction for reading from memory.
static Error ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
Parse the section specifier indicated by "Spec".
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition MDBuilder.cpp:48
Metadata node.
Definition Metadata.h:1081
ArrayRef< MDOperand > operands() const
Definition Metadata.h:1435
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
Tuple of metadata.
Definition Metadata.h:1496
This is the common base class for memset/memcpy/memmove.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase otherMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:159
Root of the metadata hierarchy.
Definition Metadata.h:64
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Evaluate the size and offset of an object pointed to by a Value* statically.
LLVM_ABI SizeOffsetAPInt compute(Value *V)
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
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
Return a value (possibly void), from a function.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void resize(size_type N)
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
LLVM_ABI bool isSafe(const AllocaInst &AI) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Class to represent struct types.
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 TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
EltTy front() const
unsigned size() const
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
Definition Triple.h:1001
bool isDriverKit() const
Is this an Apple DriverKit triple.
Definition Triple.h:708
bool isBPF() const
Tests whether the target is eBPF.
Definition Triple.h:1246
bool isOSNetBSD() const
Definition Triple.h:745
bool isAndroid() const
Tests whether the target is Android.
Definition Triple.h:911
bool isABIN32() const
Definition Triple.h:1234
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition Triple.h:1133
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:515
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition Triple.h:1122
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
Definition Triple.h:1128
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:778
@ UnknownObjectFormat
Definition Triple.h:422
bool isARM() const
Tests whether the target is ARM (little and big endian).
Definition Triple.h:1006
bool isOSLinux() const
Tests whether the OS is Linux.
Definition Triple.h:831
bool isAMDGPU() const
Definition Triple.h:998
bool isMacOSX() const
Is this a Mac OS X triple.
Definition Triple.h:682
bool isOSFreeBSD() const
Definition Triple.h:749
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition Triple.h:846
bool isWatchOS() const
Is this an Apple watchOS triple.
Definition Triple.h:697
bool isiOS() const
Is this an iOS triple.
Definition Triple.h:691
bool isPS() const
Tests whether the target is the PS4 or PS5 platform.
Definition Triple.h:908
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Definition Triple.h:1215
bool isOSFuchsia() const
Definition Triple.h:751
bool isOSHaiku() const
Tests whether the OS is Haiku.
Definition Triple.h:772
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
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 replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
Definition Value.cpp:1164
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:400
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
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
CallInst * Call
Changed
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void getInterestingMemoryOperands(Module &M, Instruction *I, SmallVectorImpl< InterestingMemoryOperand > &Interesting)
Get all the memory operands from the instruction that needs to be instrumented.
void instrumentAddress(Module &M, IRBuilder<> &IRB, Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, Align Alignment, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, bool Recover, int AsanScale, int AsanOffset)
Instrument the memory operand Addr.
uint64_t getRedzoneSizeForGlobal(int AsanScale, uint64_t SizeInBytes)
Given SizeInBytes of the Value to be instrunmented, Returns the redzone size corresponding to it.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
Definition MachO.h:131
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
LLVM_ABI uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
@ Offset
Definition DWP.cpp:577
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
LLVM_ABI GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, Twine NamePrefix="")
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
@ Done
Definition Threading.h:60
LLVM_ABI Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
AsanDetectStackUseAfterReturnMode
Mode of ASan detect stack use after return.
@ Always
Always detect stack use after return.
@ Never
Never detect stack use after return.
@ Runtime
Detect stack use after return if not disabled runtime with (ASAN_OPTIONS=detect_stack_use_after_retur...
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
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
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
Op::Description Desc
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
LLVM_ABI SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytes(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
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
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
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
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
AsanDtorKind
Types of ASan module destructors supported.
@ None
Do not emit any destructors for ASan.
LLVM_ABI ASanStackFrameLayout ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, uint64_t Granularity, uint64_t MinHeaderSize)
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ ModRef
The access may reference and may modify the value stored in memory.
Definition ModRef.h:36
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
@ ArgMem
Access to memory via argument pointers.
Definition ModRef.h:62
@ Other
Any other memory.
Definition ModRef.h:68
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
Definition ModRef.h:64
TargetTransformInfo TTI
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
OperandBundleDefT< Value * > OperandBundleDef
Definition AutoUpgrade.h:34
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
static const int kAsanStackUseAfterReturnMagic
LLVM_ABI void setGlobalVariableLargeSection(const Triple &TargetTriple, GlobalVariable &GV)
LLVM_ABI void removeASanIncompatibleFnAttributes(Function &F, bool ReadsArgMem)
Remove memory attributes that are incompatible with the instrumentation added by AddressSanitizer and...
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isModAndRefSet(const ModRefInfo MRI)
Definition ModRef.h:46
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.
TinyPtrVector< BasicBlock * > ColorVector
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
constexpr bool valueOr(BoolOrDefault X, bool Default)
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:105
iterator_range< df_iterator< T > > depth_first(const T &G)
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 ...
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
AsanCtorKind
Types of ASan module constructors supported.
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 void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
LLVM_ABI void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
Definition Demangle.cpp:21
std::string itostr(int64_t X)
LLVM_ABI void SplitBlockAndInsertForEachLane(ElementCount EC, Type *IndexTy, BasicBlock::iterator InsertBefore, std::function< void(IRBuilderBase &, Value *)> Func)
Utility function for performing a given action on each lane of a vector with EC elements.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset)
Replaces dbg.declare record when the address it describes is replaced with a new value.
Definition Local.cpp:1967
#define N
LLVM_ABI ASanAccessInfo(int32_t Packed)
const uint8_t AccessSizeIndex
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
static constexpr Align fromLog2(unsigned Log2Value)
Returns an alignment of 1 << Log2Value bytes.
Definition Alignment.h:73
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:111
Information about a load/store intrinsic defined by the target.
SmallVector< InterestingMemoryOperand, 1 > InterestingOperands
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.