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