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