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