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 = (G->getName() + "." + InternalSuffix).str();
2145 C = M.getOrInsertComdat(Name);
2146 } else {
2147 C = M.getOrInsertComdat(G->getName());
2148 }
2149
2150 // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. Also upgrade private
2151 // linkage to internal linkage so that a symbol table entry is emitted. This
2152 // is necessary in order to create the comdat group.
2153 if (TargetTriple.isOSBinFormatCOFF()) {
2154 C->setSelectionKind(Comdat::NoDeduplicate);
2155 if (G->hasPrivateLinkage())
2156 G->setLinkage(GlobalValue::InternalLinkage);
2157 }
2158 G->setComdat(C);
2159 }
2160
2161 assert(G->hasComdat());
2162 Metadata->setComdat(G->getComdat());
2163}
2164
2165// Create a separate metadata global and put it in the appropriate ASan
2166// global registration section.
2168ModuleAddressSanitizer::CreateMetadataGlobal(Constant *Initializer,
2169 StringRef OriginalName) {
2170 auto Linkage = TargetTriple.isOSBinFormatMachO()
2174 M, Initializer->getType(), false, Linkage, Initializer,
2175 Twine("__asan_global_") + GlobalValue::dropLLVMManglingEscape(OriginalName));
2176 Metadata->setSection(getGlobalMetadataSection());
2177 // Place metadata in a large section for x86-64 ELF binaries to mitigate
2178 // relocation pressure.
2180 return Metadata;
2181}
2182
2183Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2184 AsanDtorFunction = Function::createWithDefaultAttr(
2187 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2188 // Ensure Dtor cannot be discarded, even if in a comdat.
2189 appendToUsed(M, {AsanDtorFunction});
2190 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
2191
2192 return ReturnInst::Create(*C, AsanDtorBB);
2193}
2194
2195void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2196 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2197 ArrayRef<Constant *> MetadataInitializers) {
2198 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2199 auto &DL = M.getDataLayout();
2200
2201 SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
2202 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2203 Constant *Initializer = MetadataInitializers[i];
2204 GlobalVariable *G = ExtendedGlobals[i];
2205 GlobalVariable *Metadata = CreateMetadataGlobal(Initializer, G->getName());
2206 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
2207 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2208 MetadataGlobals[i] = Metadata;
2209
2210 // The MSVC linker always inserts padding when linking incrementally. We
2211 // cope with that by aligning each struct to its size, which must be a power
2212 // of two.
2213 unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
2214 assert(isPowerOf2_32(SizeOfGlobalStruct) &&
2215 "global metadata will not be padded appropriately");
2216 Metadata->setAlignment(assumeAligned(SizeOfGlobalStruct));
2217
2218 SetComdatForGlobalMetadata(G, Metadata, "");
2219 }
2220
2221 // Update llvm.compiler.used, adding the new metadata globals. This is
2222 // needed so that during LTO these variables stay alive.
2223 if (!MetadataGlobals.empty())
2224 appendToCompilerUsed(M, MetadataGlobals);
2225}
2226
2227void ModuleAddressSanitizer::instrumentGlobalsELF(
2228 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2229 ArrayRef<Constant *> MetadataInitializers,
2230 const std::string &UniqueModuleId) {
2231 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2232
2233 // Putting globals in a comdat changes the semantic and potentially cause
2234 // false negative odr violations at link time. If odr indicators are used, we
2235 // keep the comdat sections, as link time odr violations will be detected on
2236 // the odr indicator symbols.
2237 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2238
2239 SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
2240 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2241 GlobalVariable *G = ExtendedGlobals[i];
2243 CreateMetadataGlobal(MetadataInitializers[i], G->getName());
2244 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
2245 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2246 MetadataGlobals[i] = Metadata;
2247
2248 if (UseComdatForGlobalsGC)
2249 SetComdatForGlobalMetadata(G, Metadata, UniqueModuleId);
2250 }
2251
2252 // Update llvm.compiler.used, adding the new metadata globals. This is
2253 // needed so that during LTO these variables stay alive.
2254 if (!MetadataGlobals.empty())
2255 appendToCompilerUsed(M, MetadataGlobals);
2256
2257 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
2258 // to look up the loaded image that contains it. Second, we can store in it
2259 // whether registration has already occurred, to prevent duplicate
2260 // registration.
2261 //
2262 // Common linkage ensures that there is only one global per shared library.
2263 GlobalVariable *RegisteredFlag = new GlobalVariable(
2264 M, IntptrTy, false, GlobalVariable::CommonLinkage,
2265 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
2267
2268 // Create start and stop symbols.
2269 GlobalVariable *StartELFMetadata = new GlobalVariable(
2270 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2271 "__start_" + getGlobalMetadataSection());
2273 GlobalVariable *StopELFMetadata = new GlobalVariable(
2274 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2275 "__stop_" + getGlobalMetadataSection());
2277
2278 // Create a call to register the globals with the runtime.
2279 if (ConstructorKind == AsanCtorKind::Global)
2280 IRB.CreateCall(AsanRegisterElfGlobals,
2281 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
2282 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
2283 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
2284
2285 // We also need to unregister globals at the end, e.g., when a shared library
2286 // gets closed.
2287 if (DestructorKind != AsanDtorKind::None && !MetadataGlobals.empty()) {
2288 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2289 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2290 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
2291 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
2292 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
2293 }
2294}
2295
2296void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2297 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2298 ArrayRef<Constant *> MetadataInitializers) {
2299 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2300
2301 // On recent Mach-O platforms, use a structure which binds the liveness of
2302 // the global variable to the metadata struct. Keep the list of "Liveness" GV
2303 // created to be added to llvm.compiler.used
2304 StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy);
2305 SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
2306
2307 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2308 Constant *Initializer = MetadataInitializers[i];
2309 GlobalVariable *G = ExtendedGlobals[i];
2310 GlobalVariable *Metadata = CreateMetadataGlobal(Initializer, G->getName());
2311
2312 // On recent Mach-O platforms, we emit the global metadata in a way that
2313 // allows the linker to properly strip dead globals.
2314 auto LivenessBinder =
2315 ConstantStruct::get(LivenessTy, Initializer->getAggregateElement(0u),
2317 GlobalVariable *Liveness = new GlobalVariable(
2318 M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
2319 Twine("__asan_binder_") + G->getName());
2320 Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
2321 LivenessGlobals[i] = Liveness;
2322 }
2323
2324 // Update llvm.compiler.used, adding the new liveness globals. This is
2325 // needed so that during LTO these variables stay alive. The alternative
2326 // would be to have the linker handling the LTO symbols, but libLTO
2327 // current API does not expose access to the section for each symbol.
2328 if (!LivenessGlobals.empty())
2329 appendToCompilerUsed(M, LivenessGlobals);
2330
2331 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
2332 // to look up the loaded image that contains it. Second, we can store in it
2333 // whether registration has already occurred, to prevent duplicate
2334 // registration.
2335 //
2336 // common linkage ensures that there is only one global per shared library.
2337 GlobalVariable *RegisteredFlag = new GlobalVariable(
2338 M, IntptrTy, false, GlobalVariable::CommonLinkage,
2339 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
2341
2342 if (ConstructorKind == AsanCtorKind::Global)
2343 IRB.CreateCall(AsanRegisterImageGlobals,
2344 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
2345
2346 // We also need to unregister globals at the end, e.g., when a shared library
2347 // gets closed.
2348 if (DestructorKind != AsanDtorKind::None) {
2349 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2350 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2351 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
2352 }
2353}
2354
2355void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2356 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2357 ArrayRef<Constant *> MetadataInitializers) {
2358 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2359 unsigned N = ExtendedGlobals.size();
2360 assert(N > 0);
2361
2362 // On platforms that don't have a custom metadata section, we emit an array
2363 // of global metadata structures.
2364 ArrayType *ArrayOfGlobalStructTy =
2365 ArrayType::get(MetadataInitializers[0]->getType(), N);
2366 auto AllGlobals = new GlobalVariable(
2367 M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
2368 ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
2369 if (Mapping.Scale > 3)
2370 AllGlobals->setAlignment(Align::fromLog2(Mapping.Scale));
2371
2372 if (ConstructorKind == AsanCtorKind::Global)
2373 IRB.CreateCall(AsanRegisterGlobals,
2374 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
2375 ConstantInt::get(IntptrTy, N)});
2376
2377 // We also need to unregister globals at the end, e.g., when a shared library
2378 // gets closed.
2379 if (DestructorKind != AsanDtorKind::None) {
2380 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2381 IrbDtor.CreateCall(AsanUnregisterGlobals,
2382 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
2383 ConstantInt::get(IntptrTy, N)});
2384 }
2385}
2386
2387// This function replaces all global variables with new variables that have
2388// trailing redzones. It also creates a function that poisons
2389// redzones and inserts this function into llvm.global_ctors.
2390// Sets *CtorComdat to true if the global registration code emitted into the
2391// asan constructor is comdat-compatible.
2392void ModuleAddressSanitizer::instrumentGlobals(IRBuilder<> &IRB,
2393 bool *CtorComdat) {
2394 // Build set of globals that are aliased by some GA, where
2395 // getExcludedAliasedGlobal(GA) returns the relevant GlobalVariable.
2396 SmallPtrSet<const GlobalVariable *, 16> AliasedGlobalExclusions;
2397 if (CompileKernel) {
2398 for (auto &GA : M.aliases()) {
2399 if (const GlobalVariable *GV = getExcludedAliasedGlobal(GA))
2400 AliasedGlobalExclusions.insert(GV);
2401 }
2402 }
2403
2404 SmallVector<GlobalVariable *, 16> GlobalsToChange;
2405 for (auto &G : M.globals()) {
2406 if (!AliasedGlobalExclusions.count(&G) && shouldInstrumentGlobal(&G))
2407 GlobalsToChange.push_back(&G);
2408 }
2409
2410 size_t n = GlobalsToChange.size();
2411 auto &DL = M.getDataLayout();
2412
2413 // A global is described by a structure
2414 // size_t beg;
2415 // size_t size;
2416 // size_t size_with_redzone;
2417 // const char *name;
2418 // const char *module_name;
2419 // size_t has_dynamic_init;
2420 // size_t padding_for_windows_msvc_incremental_link;
2421 // size_t odr_indicator;
2422 // We initialize an array of such structures and pass it to a run-time call.
2423 StructType *GlobalStructTy =
2424 StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
2425 IntptrTy, IntptrTy, IntptrTy);
2427 SmallVector<Constant *, 16> Initializers(n);
2428
2429 for (size_t i = 0; i < n; i++) {
2430 GlobalVariable *G = GlobalsToChange[i];
2431
2433 if (G->hasSanitizerMetadata())
2434 MD = G->getSanitizerMetadata();
2435
2436 // The runtime library tries demangling symbol names in the descriptor but
2437 // functionality like __cxa_demangle may be unavailable (e.g.
2438 // -static-libstdc++). So we demangle the symbol names here.
2439 std::string NameForGlobal = G->getName().str();
2442 /*AllowMerging*/ true, genName("global"));
2443
2444 Type *Ty = G->getValueType();
2445 const uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
2446 const uint64_t RightRedzoneSize = getRedzoneSizeForGlobal(SizeInBytes);
2447 Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
2448
2449 StructType *NewTy = StructType::get(Ty, RightRedZoneTy);
2450 Constant *NewInitializer = ConstantStruct::get(
2451 NewTy, G->getInitializer(), Constant::getNullValue(RightRedZoneTy));
2452
2453 // Create a new global variable with enough space for a redzone.
2454 GlobalValue::LinkageTypes Linkage = G->getLinkage();
2455 if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage)
2457 GlobalVariable *NewGlobal = new GlobalVariable(
2458 M, NewTy, G->isConstant(), Linkage, NewInitializer, "", G,
2459 G->getThreadLocalMode(), G->getAddressSpace());
2460 NewGlobal->copyAttributesFrom(G);
2461 NewGlobal->setComdat(G->getComdat());
2462 NewGlobal->setAlignment(Align(getMinRedzoneSizeForGlobal()));
2463 // Don't fold globals with redzones. ODR violation detector and redzone
2464 // poisoning implicitly creates a dependence on the global's address, so it
2465 // is no longer valid for it to be marked unnamed_addr.
2467
2468 // Move null-terminated C strings to "__asan_cstring" section on Darwin.
2469 if (TargetTriple.isOSBinFormatMachO() && !G->hasSection() &&
2470 G->isConstant()) {
2471 auto Seq = dyn_cast<ConstantDataSequential>(G->getInitializer());
2472 if (Seq && Seq->isCString())
2473 NewGlobal->setSection("__TEXT,__asan_cstring,regular");
2474 }
2475
2476 // Transfer the debug info and type metadata. The payload starts at offset
2477 // zero so we can copy the metadata over as is.
2478 NewGlobal->copyMetadata(G, 0);
2479
2480 G->replaceAllUsesWith(NewGlobal);
2481 NewGlobal->takeName(G);
2482 G->eraseFromParent();
2483 NewGlobals[i] = NewGlobal;
2484
2485 Constant *ODRIndicator = Constant::getNullValue(IntptrTy);
2486 GlobalValue *InstrumentedGlobal = NewGlobal;
2487
2488 bool CanUsePrivateAliases =
2489 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2490 TargetTriple.isOSBinFormatWasm();
2491 if (CanUsePrivateAliases && UsePrivateAlias) {
2492 // Create local alias for NewGlobal to avoid crash on ODR between
2493 // instrumented and non-instrumented libraries.
2494 InstrumentedGlobal =
2496 }
2497
2498 // ODR should not happen for local linkage.
2499 if (NewGlobal->hasLocalLinkage()) {
2500 ODRIndicator = ConstantInt::getAllOnesValue(IntptrTy);
2501 } else if (UseOdrIndicator) {
2502 // With local aliases, we need to provide another externally visible
2503 // symbol __odr_asan_XXX to detect ODR violation.
2504 auto *ODRIndicatorSym =
2505 new GlobalVariable(M, IRB.getInt8Ty(), false, Linkage,
2507 kODRGenPrefix + NameForGlobal, nullptr,
2508 NewGlobal->getThreadLocalMode());
2509
2510 // Set meaningful attributes for indicator symbol.
2511 ODRIndicatorSym->setVisibility(NewGlobal->getVisibility());
2512 ODRIndicatorSym->setDLLStorageClass(NewGlobal->getDLLStorageClass());
2513 ODRIndicatorSym->setAlignment(Align(1));
2514 ODRIndicator = ConstantExpr::getPtrToInt(ODRIndicatorSym, IntptrTy);
2515 }
2516
2517 Constant *Initializer = ConstantStruct::get(
2518 GlobalStructTy,
2519 ConstantExpr::getPointerCast(InstrumentedGlobal, IntptrTy),
2520 ConstantInt::get(IntptrTy, SizeInBytes),
2521 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2522 ConstantExpr::getPointerCast(Name, IntptrTy),
2523 ConstantExpr::getPointerCast(getOrCreateModuleName(), IntptrTy),
2524 ConstantInt::get(IntptrTy, MD.IsDynInit),
2525 Constant::getNullValue(IntptrTy), ODRIndicator);
2526
2527 LLVM_DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
2528
2529 Initializers[i] = Initializer;
2530 }
2531
2532 // Add instrumented globals to llvm.compiler.used list to avoid LTO from
2533 // ConstantMerge'ing them.
2534 SmallVector<GlobalValue *, 16> GlobalsToAddToUsedList;
2535 for (size_t i = 0; i < n; i++) {
2536 GlobalVariable *G = NewGlobals[i];
2537 if (G->getName().empty()) continue;
2538 GlobalsToAddToUsedList.push_back(G);
2539 }
2540 appendToCompilerUsed(M, ArrayRef<GlobalValue *>(GlobalsToAddToUsedList));
2541
2542 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2543 // Use COMDAT and register globals even if n == 0 to ensure that (a) the
2544 // linkage unit will only have one module constructor, and (b) the register
2545 // function will be called. The module destructor is not created when n ==
2546 // 0.
2547 *CtorComdat = true;
2548 instrumentGlobalsELF(IRB, NewGlobals, Initializers, getUniqueModuleId(&M));
2549 } else if (n == 0) {
2550 // When UseGlobalsGC is false, COMDAT can still be used if n == 0, because
2551 // all compile units will have identical module constructor/destructor.
2552 *CtorComdat = TargetTriple.isOSBinFormatELF();
2553 } else {
2554 *CtorComdat = false;
2555 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2556 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2557 } else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2558 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2559 } else {
2560 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2561 }
2562 }
2563
2564 // Create calls for poisoning before initializers run and unpoisoning after.
2565 if (Opts.asan_initialization_order)
2566 createInitializerPoisonCalls();
2567
2568 LLVM_DEBUG(dbgs() << M);
2569}
2570
2572ModuleAddressSanitizer::getRedzoneSizeForGlobal(uint64_t SizeInBytes) const {
2573 constexpr uint64_t kMaxRZ = 1 << 18;
2574 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2575
2576 uint64_t RZ = 0;
2577 if (SizeInBytes <= MinRZ / 2) {
2578 // Reduce redzone size for small size objects, e.g. int, char[1]. MinRZ is
2579 // at least 32 bytes, optimize when SizeInBytes is less than or equal to
2580 // half of MinRZ.
2581 RZ = MinRZ - SizeInBytes;
2582 } else {
2583 // Calculate RZ, where MinRZ <= RZ <= MaxRZ, and RZ ~ 1/4 * SizeInBytes.
2584 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2585
2586 // Round up to multiple of MinRZ.
2587 if (SizeInBytes % MinRZ)
2588 RZ += MinRZ - (SizeInBytes % MinRZ);
2589 }
2590
2591 assert((RZ + SizeInBytes) % MinRZ == 0);
2592
2593 return RZ;
2594}
2595
2596int ModuleAddressSanitizer::GetAsanVersion() const {
2597 int LongSize = M.getDataLayout().getPointerSizeInBits();
2598 bool isAndroid = M.getTargetTriple().isAndroid();
2599 int Version = 8;
2600 // 32-bit Android is one version ahead because of the switch to dynamic
2601 // shadow.
2602 Version += (LongSize == 32 && isAndroid);
2603 return Version;
2604}
2605
2606GlobalVariable *ModuleAddressSanitizer::getOrCreateModuleName() {
2607 if (!ModuleName) {
2608 // We shouldn't merge same module names, as this string serves as unique
2609 // module ID in runtime.
2610 ModuleName =
2611 createPrivateGlobalForString(M, M.getModuleIdentifier(),
2612 /*AllowMerging*/ false, genName("module"));
2613 }
2614 return ModuleName;
2615}
2616
2617bool ModuleAddressSanitizer::instrumentModule() {
2618 initializeCallbacks();
2619
2620 for (Function &F : M)
2621 removeASanIncompatibleFnAttributes(F, /*ReadsArgMem=*/false);
2622
2623 // Create a module constructor. A destructor is created lazily because not all
2624 // platforms, and not all modules need it.
2625 if (ConstructorKind == AsanCtorKind::Global) {
2626 if (CompileKernel) {
2627 // The kernel always builds with its own runtime, and therefore does not
2628 // need the init and version check calls.
2629 AsanCtorFunction = createSanitizerCtor(M, kAsanModuleCtorName);
2630 } else {
2631 std::string AsanVersion = std::to_string(GetAsanVersion());
2632 std::string VersionCheckName =
2633 InsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : "";
2634 std::tie(AsanCtorFunction, std::ignore) =
2636 M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{},
2637 /*InitArgs=*/{}, VersionCheckName);
2638 }
2639 }
2640
2641 bool CtorComdat = true;
2642 if (Opts.asan_globals) {
2643 assert(AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
2644 if (AsanCtorFunction) {
2645 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2646 instrumentGlobals(IRB, &CtorComdat);
2647 } else {
2648 IRBuilder<> IRB(M);
2649 instrumentGlobals(IRB, &CtorComdat);
2650 }
2651 }
2652
2653 const uint64_t Priority = GetCtorAndDtorPriority(TargetTriple);
2654
2655 // Put the constructor and destructor in comdat if both
2656 // (1) global instrumentation is not TU-specific
2657 // (2) target is ELF.
2658 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2659 if (AsanCtorFunction) {
2660 AsanCtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleCtorName));
2661 appendToGlobalCtors(M, AsanCtorFunction, Priority, AsanCtorFunction);
2662 }
2663 if (AsanDtorFunction) {
2664 AsanDtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleDtorName));
2665 appendToGlobalDtors(M, AsanDtorFunction, Priority, AsanDtorFunction);
2666 }
2667 } else {
2668 if (AsanCtorFunction)
2669 appendToGlobalCtors(M, AsanCtorFunction, Priority);
2670 if (AsanDtorFunction)
2671 appendToGlobalDtors(M, AsanDtorFunction, Priority);
2672 }
2673
2674 return true;
2675}
2676
2677void AddressSanitizer::initializeCallbacks(const TargetLibraryInfo *TLI) {
2678 IRBuilder<> IRB(M);
2679
2680 const std::string EndingStr = Recover ? "_noabort" : "";
2681 AsanAssumeDereferenceableCallback = M.getOrInsertFunction(
2682 "__asan_report_assume_dereferenceable" + EndingStr,
2683 FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false));
2684
2685 // Create __asan_report* callbacks.
2686 // IsWrite, TypeSize and Exp are encoded in the function name.
2687 for (int Exp = 0; Exp < 2; Exp++) {
2688 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2689 const std::string TypeStr = AccessIsWrite ? "store" : "load";
2690 const std::string ExpStr = Exp ? "exp_" : "";
2691 const std::string EndingStr = Recover ? "_noabort" : "";
2692
2693 SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
2694 SmallVector<Type *, 2> Args1{1, IntptrTy};
2695 AttributeList AL2;
2696 AttributeList AL1;
2697 if (Exp) {
2698 Type *ExpType = Type::getInt32Ty(*C);
2699 Args2.push_back(ExpType);
2700 Args1.push_back(ExpType);
2701 if (auto AK = TLI->getExtAttrForI32Param(false)) {
2702 AL2 = AL2.addParamAttribute(*C, 2, AK);
2703 AL1 = AL1.addParamAttribute(*C, 1, AK);
2704 }
2705 }
2706 AsanErrorCallbackSized[AccessIsWrite][Exp] = Inserter.insertFunction(
2707 kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr,
2708 FunctionType::get(IRB.getVoidTy(), Args2, false), AL2);
2709
2710 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
2711 Inserter.insertFunction(
2712 (Opts.asan_memory_access_callback_prefix + ExpStr + TypeStr +
2713 "N" + EndingStr)
2714 .str(),
2715 FunctionType::get(IRB.getVoidTy(), Args2, false), AL2);
2716
2717 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
2718 AccessSizeIndex++) {
2719 const std::string Suffix = TypeStr + itostr(1ULL << AccessSizeIndex);
2720 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2721 Inserter.insertFunction(
2722 kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr,
2723 FunctionType::get(IRB.getVoidTy(), Args1, false), AL1);
2724
2725 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2726 Inserter.insertFunction(
2727 (Opts.asan_memory_access_callback_prefix + ExpStr + Suffix +
2728 EndingStr)
2729 .str(),
2730 FunctionType::get(IRB.getVoidTy(), Args1, false), AL1);
2731 }
2732 }
2733 }
2734
2735 const std::string MemIntrinCallbackPrefix =
2736 (CompileKernel && !Opts.asan_kernel_mem_intrinsic_prefix)
2737 ? std::string("")
2738 : Opts.asan_memory_access_callback_prefix.str();
2739 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix + "memmove",
2740 PtrTy, PtrTy, PtrTy, IntptrTy);
2741 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix + "memcpy",
2742 PtrTy, PtrTy, PtrTy, IntptrTy);
2743 AsanMemset =
2744 Inserter.insertFunction(MemIntrinCallbackPrefix + "memset",
2745 TLI->getAttrList(C, {1},
2746 /*Signed=*/false),
2747 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
2748
2749 AsanHandleNoReturnFunc =
2750 Inserter.insertFunction(kAsanHandleNoReturnName, IRB.getVoidTy());
2751
2752 AsanPtrCmpFunction =
2753 Inserter.insertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy);
2754 AsanPtrSubFunction =
2755 Inserter.insertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy);
2756 if (Mapping.InGlobal)
2757 AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow",
2758 ArrayType::get(IRB.getInt8Ty(), 0));
2759
2760 AMDGPUAddressShared =
2761 Inserter.insertFunction(kAMDGPUAddressSharedName, IRB.getInt1Ty(), PtrTy);
2762 AMDGPUAddressPrivate = Inserter.insertFunction(kAMDGPUAddressPrivateName,
2763 IRB.getInt1Ty(), PtrTy);
2764}
2765
2766bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
2767 // For each NSObject descendant having a +load method, this method is invoked
2768 // by the ObjC runtime before any of the static constructors is called.
2769 // Therefore we need to instrument such methods with a call to __asan_init
2770 // at the beginning in order to initialize our runtime before any access to
2771 // the shadow memory.
2772 // We cannot just ignore these methods, because they may call other
2773 // instrumented functions.
2774 if (F.getName().contains(" load]")) {
2775 FunctionCallee AsanInitFunction =
2776 declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {});
2777 IRBuilder<> IRB(F.front().begin());
2778 IRB.CreateCall(AsanInitFunction, {});
2779 return true;
2780 }
2781 return false;
2782}
2783
2784bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(Function &F) {
2785 // Generate code only when dynamic addressing is needed.
2786 if (Mapping.Offset != kDynamicShadowSentinel)
2787 return false;
2788
2789 IRBuilder<> IRB(&F.front().front());
2790 if (Mapping.InGlobal) {
2791 if (Opts.asan_with_ifunc_suppress_remat) {
2792 // An empty inline asm with input reg == output reg.
2793 // An opaque pointer-to-int cast, basically.
2795 FunctionType::get(IntptrTy, {AsanShadowGlobal->getType()}, false),
2796 StringRef(""), StringRef("=r,0"),
2797 /*hasSideEffects=*/false);
2798 LocalDynamicShadow =
2799 IRB.CreateCall(Asm, {AsanShadowGlobal}, ".asan.shadow");
2800 } else {
2801 LocalDynamicShadow =
2802 IRB.CreatePointerCast(AsanShadowGlobal, IntptrTy, ".asan.shadow");
2803 }
2804 } else {
2805 Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
2807 LocalDynamicShadow = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
2808 }
2809 return true;
2810}
2811
2812void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
2813 // Find the one possible call to llvm.localescape and pre-mark allocas passed
2814 // to it as uninteresting. This assumes we haven't started processing allocas
2815 // yet. This check is done up front because iterating the use list in
2816 // isInterestingAlloca would be algorithmically slower.
2817 assert(ProcessedAllocas.empty() && "must process localescape before allocas");
2818
2819 // Try to get the declaration of llvm.localescape. If it's not in the module,
2820 // we can exit early.
2821 if (!F.getParent()->getFunction("llvm.localescape")) return;
2822
2823 // Look for a call to llvm.localescape call in the entry block. It can't be in
2824 // any other block.
2825 for (Instruction &I : F.getEntryBlock()) {
2827 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
2828 // We found a call. Mark all the allocas passed in as uninteresting.
2829 for (Value *Arg : II->args()) {
2830 AllocaInst *AI = dyn_cast<AllocaInst>(Arg->stripPointerCasts());
2831 assert(AI && AI->isStaticAlloca() &&
2832 "non-static alloca arg to localescape");
2833 ProcessedAllocas[AI] = false;
2834 }
2835 break;
2836 }
2837 }
2838}
2839// Mitigation for https://github.com/google/sanitizers/issues/749
2840// We don't instrument Windows catch-block parameters to avoid
2841// interfering with exception handling assumptions.
2842void AddressSanitizer::markCatchParametersAsUninteresting(Function &F) {
2843 for (BasicBlock &BB : F) {
2844 for (Instruction &I : BB) {
2845 if (auto *CatchPad = dyn_cast<CatchPadInst>(&I)) {
2846 // Mark the parameters to a catch-block as uninteresting to avoid
2847 // instrumenting them.
2848 for (Value *Operand : CatchPad->arg_operands())
2849 if (auto *AI = dyn_cast<AllocaInst>(Operand))
2850 ProcessedAllocas[AI] = false;
2851 }
2852 }
2853 }
2854}
2855
2856bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) {
2857 bool ShouldInstrument = Opts.asan_debug_min < 0 || Opts.asan_debug_max < 0 ||
2858 (Instrumented >= Opts.asan_debug_min &&
2859 Instrumented <= Opts.asan_debug_max);
2860 Instrumented++;
2861 return !ShouldInstrument;
2862}
2863
2864bool AddressSanitizer::instrumentFunction(Function &F,
2865 const TargetLibraryInfo *TLI,
2866 const TargetTransformInfo *TTI) {
2867 bool FunctionModified = false;
2868
2869 // Do not apply any instrumentation for naked functions.
2870 if (F.hasFnAttribute(Attribute::Naked))
2871 return FunctionModified;
2872
2873 // If needed, insert __asan_init before checking for SanitizeAddress attr.
2874 // This function needs to be called even if the function body is not
2875 // instrumented.
2876 if (maybeInsertAsanInitAtFunctionEntry(F))
2877 FunctionModified = true;
2878
2879 // Leave if the function doesn't need instrumentation.
2880 if (!F.hasFnAttribute(Attribute::SanitizeAddress)) return FunctionModified;
2881
2882 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2883 return FunctionModified;
2884
2885 LLVM_DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
2886
2887 initializeCallbacks(TLI);
2888
2889 FunctionStateRAII CleanupObj(this);
2890
2891 RuntimeCallInserter RTCI(F);
2892
2893 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(F);
2894
2895 // We can't instrument allocas used with llvm.localescape. Only static allocas
2896 // can be passed to that intrinsic.
2897 markEscapedLocalAllocas(F);
2898
2899 if (TargetTriple.isOSWindows())
2900 markCatchParametersAsUninteresting(F);
2901
2902 // We want to instrument every address only once per basic block (unless there
2903 // are calls between uses).
2904 SmallPtrSet<Value *, 16> TempsToInstrument;
2905 SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
2906 SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
2907 SmallVector<Instruction *, 8> NoReturnCalls;
2909 SmallVector<Instruction *, 16> PointerComparisonsOrSubtracts;
2910 SmallVector<AssumeInst *, 8> DerefAssumptions;
2911
2912 // Fill the set of memory operations to instrument.
2913 for (auto &BB : F) {
2914 AllBlocks.push_back(&BB);
2915 TempsToInstrument.clear();
2916 int NumInsnsPerBB = 0;
2917 for (auto &Inst : BB) {
2918 if (LooksLikeCodeInBug11395(&Inst)) return false;
2919 // Skip instructions inserted by another instrumentation.
2920 if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
2921 continue;
2922 SmallVector<InterestingMemoryOperand, 1> InterestingOperands;
2923 getInterestingMemoryOperands(&Inst, InterestingOperands, TTI);
2924
2925 AssumeInst *AI;
2926 if (!InterestingOperands.empty()) {
2927 for (auto &Operand : InterestingOperands) {
2928 if (Opts.asan_opt && Opts.asan_opt_same_temp) {
2929 Value *Ptr = Operand.getPtr();
2930 // If we have a mask, skip instrumentation if we've already
2931 // instrumented the full object. But don't add to TempsToInstrument
2932 // because we might get another load/store with a different mask.
2933 if (Operand.MaybeMask) {
2934 if (TempsToInstrument.count(Ptr))
2935 continue; // We've seen this (whole) temp in the current BB.
2936 } else {
2937 if (!TempsToInstrument.insert(Ptr).second)
2938 continue; // We've seen this temp in the current BB.
2939 }
2940 }
2941 OperandsToInstrument.push_back(Operand);
2942 NumInsnsPerBB++;
2943 }
2944 } else if (((Opts.asan_detect_invalid_pointer_pair ||
2945 Opts.asan_detect_invalid_pointer_cmp) &&
2947 ((Opts.asan_detect_invalid_pointer_pair ||
2948 Opts.asan_detect_invalid_pointer_sub) &&
2950 PointerComparisonsOrSubtracts.push_back(&Inst);
2951 } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst)) {
2952 // ok, take it.
2953 IntrinToInstrument.push_back(MI);
2954 NumInsnsPerBB++;
2955 } else if (Opts.asan_instrument_assume_dereferenceable &&
2956 (AI = dyn_cast<AssumeInst>(&Inst))) {
2957 if (AI->getOperandBundle("dereferenceable")) {
2958 DerefAssumptions.push_back(AI);
2959 NumInsnsPerBB++;
2960 }
2961 } else {
2962 if (auto *CB = dyn_cast<CallBase>(&Inst)) {
2963 // A call inside BB.
2964 TempsToInstrument.clear();
2965 if (CB->doesNotReturn())
2966 NoReturnCalls.push_back(CB);
2967 }
2968 if (CallInst *CI = dyn_cast<CallInst>(&Inst))
2970 }
2971 if (NumInsnsPerBB >= Opts.asan_max_ins_per_bb)
2972 break;
2973 }
2974 }
2975
2976 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
2977 OperandsToInstrument.size() + IntrinToInstrument.size() >
2978 (unsigned)InstrumentationWithCallsThreshold);
2979 const DataLayout &DL = F.getDataLayout();
2980 ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext());
2981
2982 // Instrument.
2983 int NumInstrumented = 0;
2984 for (auto &Operand : OperandsToInstrument) {
2985 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2986 instrumentMop(ObjSizeVis, Operand, UseCalls,
2987 F.getDataLayout(), RTCI);
2988 FunctionModified = true;
2989 }
2990 for (auto *Inst : IntrinToInstrument) {
2991 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2992 instrumentMemIntrinsic(Inst, RTCI);
2993 FunctionModified = true;
2994 }
2995
2996 FunctionStackPoisoner FSP(F, *this, RTCI);
2997 bool ChangedStack = FSP.runOnFunction();
2998
2999 // We must unpoison the stack before NoReturn calls (throw, _exit, etc).
3000 // See e.g. https://github.com/google/sanitizers/issues/37
3001 for (auto *CI : NoReturnCalls) {
3002 IRBuilder<> IRB(CI);
3003 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3004 }
3005
3006 for (auto *Inst : PointerComparisonsOrSubtracts) {
3007 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3008 }
3009
3010 for (auto *AI : DerefAssumptions) {
3011 if (auto Bundle = AI->getOperandBundle("dereferenceable")) {
3012 Value *Ptr = Bundle->Inputs[0];
3013 Value *Size = Bundle->Inputs[1];
3014
3015 // Skip if size is exactly 0 without generating IR.
3016 if (auto *CI = dyn_cast<ConstantInt>(Size)) {
3017 if (CI->getValue().zextOrTrunc(IntptrTy->getIntegerBitWidth()).isZero())
3018 continue;
3019 }
3020
3021 IRBuilder<> IRB(AI);
3022 Value *AddrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
3023 Value *SizeExt = IRB.CreateZExtOrTrunc(Size, IntptrTy);
3024
3025 RTCI.createRuntimeCall(IRB, AsanAssumeDereferenceableCallback,
3026 {AddrLong, SizeExt});
3027
3028 FunctionModified = true;
3029 }
3030 }
3031
3032 if (ChangedStack || !NoReturnCalls.empty())
3033 FunctionModified = true;
3034
3035 LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " "
3036 << F << "\n");
3037
3038 return FunctionModified;
3039}
3040
3041// Workaround for bug 11395: we don't want to instrument stack in functions
3042// with large assembly blobs (32-bit only), otherwise reg alloc may crash.
3043// FIXME: remove once the bug 11395 is fixed.
3044bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) {
3045 if (LongSize != 32) return false;
3047 if (!CI || !CI->isInlineAsm()) return false;
3048 if (CI->arg_size() <= 5)
3049 return false;
3050 // We have inline assembly with quite a few arguments.
3051 return true;
3052}
3053
3054void FunctionStackPoisoner::initializeCallbacks(Module &M) {
3055 IRBuilder<> IRB(M);
3056 if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always ||
3057 ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
3058 const char *MallocNameTemplate =
3059 ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always
3062 for (int Index = 0; Index <= kMaxAsanStackMallocSizeClass; Index++) {
3063 std::string Suffix = itostr(Index);
3064 AsanStackMallocFunc[Index] = ASan.Inserter.insertFunction(
3065 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3066 AsanStackFreeFunc[Index] =
3067 ASan.Inserter.insertFunction(kAsanStackFreeNameTemplate + Suffix,
3068 IRB.getVoidTy(), IntptrTy, IntptrTy);
3069 }
3070 }
3071 if (ASan.UseAfterScope) {
3072 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3073 kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
3074 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3075 kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
3076 }
3077
3078 for (size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3079 0xf3, 0xf5, 0xf8}) {
3080 std::ostringstream Name;
3082 Name << std::setw(2) << std::setfill('0') << std::hex << Val;
3083 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3084 Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy);
3085 }
3086
3087 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3088 kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
3089 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3090 kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
3091}
3092
3093void FunctionStackPoisoner::copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
3094 ArrayRef<uint8_t> ShadowBytes,
3095 size_t Begin, size_t End,
3096 IRBuilder<> &IRB,
3097 Value *ShadowBase) {
3098 if (Begin >= End)
3099 return;
3100
3101 const size_t LargestStoreSizeInBytes =
3102 std::min<size_t>(sizeof(uint64_t), ASan.LongSize / 8);
3103
3104 const bool IsLittleEndian = F.getDataLayout().isLittleEndian();
3105
3106 // Poison given range in shadow using larges store size with out leading and
3107 // trailing zeros in ShadowMask. Zeros never change, so they need neither
3108 // poisoning nor up-poisoning. Still we don't mind if some of them get into a
3109 // middle of a store.
3110 for (size_t i = Begin; i < End;) {
3111 if (!ShadowMask[i]) {
3112 assert(!ShadowBytes[i]);
3113 ++i;
3114 continue;
3115 }
3116
3117 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3118 // Fit store size into the range.
3119 while (StoreSizeInBytes > End - i)
3120 StoreSizeInBytes /= 2;
3121
3122 // Minimize store size by trimming trailing zeros.
3123 for (size_t j = StoreSizeInBytes - 1; j && !ShadowMask[i + j]; --j) {
3124 while (j <= StoreSizeInBytes / 2)
3125 StoreSizeInBytes /= 2;
3126 }
3127
3128 uint64_t Val = 0;
3129 for (size_t j = 0; j < StoreSizeInBytes; j++) {
3130 if (IsLittleEndian)
3131 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
3132 else
3133 Val = (Val << 8) | ShadowBytes[i + j];
3134 }
3135
3136 Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3137 Value *Poison = IRB.getIntN(StoreSizeInBytes * 8, Val);
3139 Poison, IRB.CreateIntToPtr(Ptr, PointerType::getUnqual(Poison->getContext())),
3140 Align(1));
3141
3142 i += StoreSizeInBytes;
3143 }
3144}
3145
3146void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
3147 ArrayRef<uint8_t> ShadowBytes,
3148 IRBuilder<> &IRB, Value *ShadowBase) {
3149 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.size(), IRB, ShadowBase);
3150}
3151
3152void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
3153 ArrayRef<uint8_t> ShadowBytes,
3154 size_t Begin, size_t End,
3155 IRBuilder<> &IRB, Value *ShadowBase) {
3156 assert(ShadowMask.size() == ShadowBytes.size());
3157 size_t Done = Begin;
3158 for (size_t i = Begin, j = Begin + 1; i < End; i = j++) {
3159 if (!ShadowMask[i]) {
3160 assert(!ShadowBytes[i]);
3161 continue;
3162 }
3163 uint8_t Val = ShadowBytes[i];
3164 if (!AsanSetShadowFunc[Val])
3165 continue;
3166
3167 // Skip same values.
3168 for (; j < End && ShadowMask[j] && Val == ShadowBytes[j]; ++j) {
3169 }
3170
3171 if (j - i >= ASan.MaxInlinePoisoningSize) {
3172 copyToShadowInline(ShadowMask, ShadowBytes, Done, i, IRB, ShadowBase);
3173 RTCI.createRuntimeCall(
3174 IRB, AsanSetShadowFunc[Val],
3175 {IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3176 ConstantInt::get(IntptrTy, j - i)});
3177 Done = j;
3178 }
3179 }
3180
3181 copyToShadowInline(ShadowMask, ShadowBytes, Done, End, IRB, ShadowBase);
3182}
3183
3184// Fake stack allocator (asan_fake_stack.h) has 11 size classes
3185// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass
3186static int StackMallocSizeClass(uint64_t LocalStackSize) {
3187 assert(LocalStackSize <= kMaxStackMallocSize);
3188 uint64_t MaxSize = kMinStackMallocSize;
3189 for (int i = 0;; i++, MaxSize *= 2)
3190 if (LocalStackSize <= MaxSize) return i;
3191 llvm_unreachable("impossible LocalStackSize");
3192}
3193
3194void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3195 Instruction *CopyInsertPoint = &F.front().front();
3196 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3197 // Insert after the dynamic shadow location is determined
3198 CopyInsertPoint = CopyInsertPoint->getNextNode();
3199 assert(CopyInsertPoint);
3200 }
3201 IRBuilder<> IRB(CopyInsertPoint);
3202 const DataLayout &DL = F.getDataLayout();
3203 for (Argument &Arg : F.args()) {
3204 if (Arg.hasByValAttr()) {
3205 Type *Ty = Arg.getParamByValType();
3206 const Align Alignment =
3207 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3208
3209 AllocaInst *AI = IRB.CreateAlloca(
3210 Ty, nullptr,
3211 (Arg.hasName() ? Arg.getName() : "Arg" + Twine(Arg.getArgNo())) +
3212 ".byval");
3213 AI->setAlignment(Alignment);
3214 Arg.replaceAllUsesWith(AI);
3215
3216 uint64_t AllocSize = DL.getTypeAllocSize(Ty);
3217 IRB.CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3218 }
3219 }
3220}
3221
3222PHINode *FunctionStackPoisoner::createPHI(IRBuilder<> &IRB, Value *Cond,
3223 Value *ValueIfTrue,
3224 Instruction *ThenTerm,
3225 Value *ValueIfFalse) {
3226 PHINode *PHI = IRB.CreatePHI(ValueIfTrue->getType(), 2);
3227 BasicBlock *CondBlock = cast<Instruction>(Cond)->getParent();
3228 PHI->addIncoming(ValueIfFalse, CondBlock);
3229 BasicBlock *ThenBlock = ThenTerm->getParent();
3230 PHI->addIncoming(ValueIfTrue, ThenBlock);
3231 return PHI;
3232}
3233
3234Value *FunctionStackPoisoner::createAllocaForLayout(
3235 IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) {
3236 AllocaInst *Alloca;
3237 if (Dynamic) {
3238 Alloca = IRB.CreateAlloca(IRB.getInt8Ty(),
3239 ConstantInt::get(IRB.getInt64Ty(), L.FrameSize),
3240 "MyAlloca");
3241 } else {
3242 Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize),
3243 nullptr, "MyAlloca");
3244 assert(Alloca->isStaticAlloca());
3245 }
3246 assert((Opts.asan_realign_stack & (Opts.asan_realign_stack - 1)) == 0);
3247 uint64_t FrameAlignment =
3248 std::max(L.FrameAlignment, uint64_t(Opts.asan_realign_stack));
3249 Alloca->setAlignment(Align(FrameAlignment));
3250 return Alloca;
3251}
3252
3253void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3254 BasicBlock &FirstBB = *F.begin();
3255 IRBuilder<> IRB(dyn_cast<Instruction>(FirstBB.begin()));
3256 DynamicAllocaLayout = IRB.CreateAlloca(IntptrTy, nullptr);
3257 IRB.CreateStore(Constant::getNullValue(IntptrTy), DynamicAllocaLayout);
3258 DynamicAllocaLayout->setAlignment(Align(32));
3259}
3260
3261void FunctionStackPoisoner::processDynamicAllocas() {
3262 if (!Opts.asan_instrument_dynamic_allocas || DynamicAllocaVec.empty()) {
3263 assert(DynamicAllocaPoisonCallVec.empty());
3264 return;
3265 }
3266
3267 // Insert poison calls for lifetime intrinsics for dynamic allocas.
3268 for (const auto &APC : DynamicAllocaPoisonCallVec) {
3269 assert(APC.InsBefore);
3270 assert(APC.AI);
3271 assert(ASan.isInterestingAlloca(*APC.AI));
3272 assert(!APC.AI->isStaticAlloca());
3273
3274 IRBuilder<> IRB(APC.InsBefore);
3275 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3276 // Dynamic allocas will be unpoisoned unconditionally below in
3277 // unpoisonDynamicAllocas.
3278 // Flag that we need unpoison static allocas.
3279 }
3280
3281 // Handle dynamic allocas.
3282 createDynamicAllocasInitStorage();
3283 for (auto &AI : DynamicAllocaVec)
3284 handleDynamicAllocaCall(AI);
3285 unpoisonDynamicAllocas();
3286}
3287
3288/// Collect instructions in the entry block after \p InsBefore which initialize
3289/// permanent storage for a function argument. These instructions must remain in
3290/// the entry block so that uninitialized values do not appear in backtraces. An
3291/// added benefit is that this conserves spill slots. This does not move stores
3292/// before instrumented / "interesting" allocas.
3294 AddressSanitizer &ASan, Instruction &InsBefore,
3295 SmallVectorImpl<Instruction *> &InitInsts) {
3296 Instruction *Start = InsBefore.getNextNode();
3297 for (Instruction *It = Start; It; It = It->getNextNode()) {
3298 // Argument initialization looks like:
3299 // 1) store <Argument>, <Alloca> OR
3300 // 2) <CastArgument> = cast <Argument> to ...
3301 // store <CastArgument> to <Alloca>
3302 // Do not consider any other kind of instruction.
3303 //
3304 // Note: This covers all known cases, but may not be exhaustive. An
3305 // alternative to pattern-matching stores is to DFS over all Argument uses:
3306 // this might be more general, but is probably much more complicated.
3307 if (isa<AllocaInst>(It) || isa<CastInst>(It))
3308 continue;
3309 if (auto *Store = dyn_cast<StoreInst>(It)) {
3310 // The store destination must be an alloca that isn't interesting for
3311 // ASan to instrument. These are moved up before InsBefore, and they're
3312 // not interesting because allocas for arguments can be mem2reg'd.
3313 auto *Alloca = dyn_cast<AllocaInst>(Store->getPointerOperand());
3314 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3315 continue;
3316
3317 Value *Val = Store->getValueOperand();
3318 bool IsDirectArgInit = isa<Argument>(Val);
3319 bool IsArgInitViaCast =
3320 isa<CastInst>(Val) &&
3321 isa<Argument>(cast<CastInst>(Val)->getOperand(0)) &&
3322 // Check that the cast appears directly before the store. Otherwise
3323 // moving the cast before InsBefore may break the IR.
3324 Val == It->getPrevNode();
3325 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3326 if (!IsArgInit)
3327 continue;
3328
3329 if (IsArgInitViaCast)
3330 InitInsts.push_back(cast<Instruction>(Val));
3331 InitInsts.push_back(Store);
3332 continue;
3333 }
3334
3335 // Do not reorder past unknown instructions: argument initialization should
3336 // only involve casts and stores.
3337 return;
3338 }
3339}
3340
3342 // Alloca could have been renamed for uniqueness. Its true name will have been
3343 // recorded as an annotation.
3344 if (AI->hasMetadata(LLVMContext::MD_annotation)) {
3345 MDTuple *AllocaAnnotations =
3346 cast<MDTuple>(AI->getMetadata(LLVMContext::MD_annotation));
3347 for (auto &Annotation : AllocaAnnotations->operands()) {
3348 if (!isa<MDTuple>(Annotation))
3349 continue;
3350 auto AnnotationTuple = cast<MDTuple>(Annotation);
3351 for (unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3352 Index++) {
3353 // All annotations are strings
3354 auto MetadataString =
3355 cast<MDString>(AnnotationTuple->getOperand(Index));
3356 if (MetadataString->getString() == "alloca_name_altered")
3357 return cast<MDString>(AnnotationTuple->getOperand(Index + 1))
3358 ->getString();
3359 }
3360 }
3361 }
3362 return AI->getName();
3363}
3364
3365void FunctionStackPoisoner::processStaticAllocas() {
3366 if (AllocaVec.empty()) {
3367 assert(StaticAllocaPoisonCallVec.empty());
3368 return;
3369 }
3370
3371 int StackMallocIdx = -1;
3372 DebugLoc EntryDebugLocation;
3373 if (auto SP = F.getSubprogram())
3374 EntryDebugLocation =
3375 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
3376
3377 Instruction *InsBefore = AllocaVec[0];
3378 IRBuilder<> IRB(InsBefore);
3379
3380 // Make sure non-instrumented allocas stay in the entry block. Otherwise,
3381 // debug info is broken, because only entry-block allocas are treated as
3382 // regular stack slots.
3383 auto InsBeforeB = InsBefore->getParent();
3384 assert(InsBeforeB == &F.getEntryBlock());
3385 for (auto *AI : StaticAllocasToMoveUp)
3386 if (AI->getParent() == InsBeforeB)
3387 AI->moveBefore(InsBefore->getIterator());
3388
3389 // Move stores of arguments into entry-block allocas as well. This prevents
3390 // extra stack slots from being generated (to house the argument values until
3391 // they can be stored into the allocas). This also prevents uninitialized
3392 // values from being shown in backtraces.
3393 SmallVector<Instruction *, 8> ArgInitInsts;
3394 findStoresToUninstrumentedArgAllocas(ASan, *InsBefore, ArgInitInsts);
3395 for (Instruction *ArgInitInst : ArgInitInsts)
3396 ArgInitInst->moveBefore(InsBefore->getIterator());
3397
3398 // If we have a call to llvm.localescape, keep it in the entry block.
3399 if (LocalEscapeCall)
3400 LocalEscapeCall->moveBefore(InsBefore->getIterator());
3401
3403 SVD.reserve(AllocaVec.size());
3404 for (AllocaInst *AI : AllocaVec) {
3407 ASan.getAllocaSizeInBytes(*AI),
3408 0,
3409 AI->getAlign().value(),
3410 AI,
3411 0,
3412 0};
3413 SVD.push_back(D);
3414 }
3415
3416 // Minimal header size (left redzone) is 4 pointers,
3417 // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms.
3418 uint64_t Granularity = 1ULL << Mapping.Scale;
3419 uint64_t MinHeaderSize = std::max((uint64_t)ASan.LongSize / 2, Granularity);
3420 const ASanStackFrameLayout &L =
3421 ComputeASanStackFrameLayout(SVD, Granularity, MinHeaderSize);
3422
3423 // Build AllocaToSVDMap for ASanStackVariableDescription lookup.
3425 for (auto &Desc : SVD)
3426 AllocaToSVDMap[Desc.AI] = &Desc;
3427
3428 // Update SVD with information from lifetime intrinsics.
3429 for (const auto &APC : StaticAllocaPoisonCallVec) {
3430 assert(APC.InsBefore);
3431 assert(APC.AI);
3432 assert(ASan.isInterestingAlloca(*APC.AI));
3433 assert(APC.AI->isStaticAlloca());
3434
3435 ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI];
3436 Desc.LifetimeSize = Desc.Size;
3437 if (const DILocation *FnLoc = EntryDebugLocation.get()) {
3438 if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3439 if (LifetimeLoc->getFile() == FnLoc->getFile())
3440 if (unsigned Line = LifetimeLoc->getLine())
3441 Desc.Line = std::min(Desc.Line ? Desc.Line : Line, Line);
3442 }
3443 }
3444 }
3445
3446 auto DescriptionString = ComputeASanStackFrameDescription(SVD);
3447 LLVM_DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n");
3448 uint64_t LocalStackSize = L.FrameSize;
3449 bool DoStackMalloc =
3450 ASan.UseAfterReturn != AsanDetectStackUseAfterReturnMode::Never &&
3451 !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize;
3452 bool DoDynamicAlloca = Opts.asan_stack_dynamic_alloca;
3453 // Don't do dynamic alloca or stack malloc if:
3454 // 1) There is inline asm: too often it makes assumptions on which registers
3455 // are available.
3456 // 2) There is a returns_twice call (typically setjmp), which is
3457 // optimization-hostile, and doesn't play well with introduced indirect
3458 // register-relative calculation of local variable addresses.
3459 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3460 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3461
3462 Type *PtrTy = F.getDataLayout().getAllocaPtrType(F.getContext());
3463 Value *StaticAlloca =
3464 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false);
3465
3466 Value *FakeStackPtr;
3467 Value *FakeStackInt;
3468 Value *LocalStackBase;
3469 Value *LocalStackBaseAlloca;
3470 uint8_t DIExprFlags = DIExpression::ApplyOffset;
3471
3472 if (DoStackMalloc) {
3473 LocalStackBaseAlloca =
3474 IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base");
3475 if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
3476 // void *FakeStack = __asan_option_detect_stack_use_after_return
3477 // ? __asan_stack_malloc_N(LocalStackSize)
3478 // : nullptr;
3479 // void *LocalStackBase = (FakeStack) ? FakeStack :
3480 // alloca(LocalStackSize);
3481 Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal(
3483 Value *UseAfterReturnIsEnabled = IRB.CreateICmpNE(
3484 IRB.CreateLoad(IRB.getInt32Ty(), OptionDetectUseAfterReturn),
3486 Instruction *Term =
3487 SplitBlockAndInsertIfThen(UseAfterReturnIsEnabled, InsBefore, false);
3488 IRBuilder<> IRBIf(Term);
3489 StackMallocIdx = StackMallocSizeClass(LocalStackSize);
3490 assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass);
3491 Value *FakeStackValue =
3492 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3493 ConstantInt::get(IntptrTy, LocalStackSize));
3494 IRB.SetInsertPoint(InsBefore);
3495 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3496 Term, ConstantInt::get(IntptrTy, 0));
3497 } else {
3498 // assert(ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode:Always)
3499 // void *FakeStack = __asan_stack_malloc_N(LocalStackSize);
3500 // void *LocalStackBase = (FakeStack) ? FakeStack :
3501 // alloca(LocalStackSize);
3502 StackMallocIdx = StackMallocSizeClass(LocalStackSize);
3503 FakeStackInt =
3504 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3505 ConstantInt::get(IntptrTy, LocalStackSize));
3506 }
3507 FakeStackPtr = IRB.CreateIntToPtr(FakeStackInt, PtrTy);
3508 Value *NoFakeStack =
3509 IRB.CreateICmpEQ(FakeStackInt, Constant::getNullValue(IntptrTy));
3510 Instruction *Term =
3511 SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false);
3512 IRBuilder<> IRBIf(Term);
3513 Value *AllocaValue =
3514 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca;
3515
3516 IRB.SetInsertPoint(InsBefore);
3517 LocalStackBase =
3518 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3519 IRB.CreateStore(LocalStackBase, LocalStackBaseAlloca);
3520 DIExprFlags |= DIExpression::DerefBefore;
3521 } else {
3522 // void *FakeStack = nullptr;
3523 // void *LocalStackBase = alloca(LocalStackSize);
3524 FakeStackInt = Constant::getNullValue(IntptrTy);
3525 FakeStackPtr = Constant::getNullValue(PtrTy);
3526 LocalStackBase =
3527 DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca;
3528 LocalStackBaseAlloca = LocalStackBase;
3529 }
3530
3531 // Replace Alloca instructions with base+offset.
3532 SmallVector<Value *> NewAllocaPtrs;
3533 for (const auto &Desc : SVD) {
3534 AllocaInst *AI = Desc.AI;
3535 replaceDbgDeclare(AI, LocalStackBaseAlloca, DIB, DIExprFlags, Desc.Offset);
3536 Value *NewAllocaPtr =
3537 IRB.CreatePtrAddWithUnsignedOffset(LocalStackBase, Desc.Offset);
3538 if (NewAllocaPtr->getType() != AI->getType())
3539 NewAllocaPtr = IRB.CreateAddrSpaceCast(NewAllocaPtr, AI->getType());
3540 AI->replaceAllUsesWith(NewAllocaPtr);
3541 NewAllocaPtrs.push_back(NewAllocaPtr);
3542 }
3543
3544 // The left-most redzone has enough space for at least 4 pointers.
3545 // Write the Magic value to redzone[0].
3546 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic),
3547 LocalStackBase);
3548 // Write the frame description constant to redzone[1].
3549 Value *BasePlus1 =
3550 IRB.CreatePtrAddWithUnsignedOffset(LocalStackBase, ASan.LongSize / 8);
3551 GlobalVariable *StackDescriptionGlobal =
3552 createPrivateGlobalForString(*F.getParent(), DescriptionString,
3553 /*AllowMerging*/ true, genName("stack"));
3554 Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy);
3555 IRB.CreateStore(Description, BasePlus1);
3556 // Write the PC to redzone[2].
3557 Value *BasePlus2 =
3558 IRB.CreatePtrAddWithUnsignedOffset(LocalStackBase, 2 * ASan.LongSize / 8);
3559 IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2);
3560
3561 const auto &ShadowAfterScope = GetShadowBytesAfterScope(SVD, L);
3562
3563 // Poison the stack red zones at the entry.
3564 Value *ShadowBase =
3565 ASan.memToShadow(IRB.CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3566 // As mask we must use most poisoned case: red zones and after scope.
3567 // As bytes we can use either the same or just red zones only.
3568 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3569
3570 if (!StaticAllocaPoisonCallVec.empty()) {
3571 const auto &ShadowInScope = GetShadowBytes(SVD, L);
3572
3573 // Poison static allocas near lifetime intrinsics.
3574 for (const auto &APC : StaticAllocaPoisonCallVec) {
3575 const ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI];
3576 assert(Desc.Offset % L.Granularity == 0);
3577 size_t Begin = Desc.Offset / L.Granularity;
3578 size_t End = Begin + (APC.Size + L.Granularity - 1) / L.Granularity;
3579
3580 IRBuilder<> IRB(APC.InsBefore);
3581 copyToShadow(ShadowAfterScope,
3582 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3583 IRB, ShadowBase);
3584 }
3585 }
3586
3587 // Remove lifetime markers now that these are no longer allocas.
3588 for (Value *NewAllocaPtr : NewAllocaPtrs) {
3589 for (User *U : make_early_inc_range(NewAllocaPtr->users())) {
3590 auto *I = cast<Instruction>(U);
3591 if (I->isLifetimeStartOrEnd())
3592 I->eraseFromParent();
3593 }
3594 }
3595
3596 SmallVector<uint8_t, 64> ShadowClean(ShadowAfterScope.size(), 0);
3597 SmallVector<uint8_t, 64> ShadowAfterReturn;
3598
3599 // (Un)poison the stack before all ret instructions.
3600 for (Instruction *Ret : RetVec) {
3601 IRBuilder<> IRBRet(Ret);
3602 // Mark the current frame as retired.
3603 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),
3604 LocalStackBase);
3605 if (DoStackMalloc) {
3606 assert(StackMallocIdx >= 0);
3607 // if FakeStack != 0 // LocalStackBase == FakeStack
3608 // // In use-after-return mode, poison the whole stack frame.
3609 // if StackMallocIdx <= 4
3610 // // For small sizes inline the whole thing:
3611 // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
3612 // **SavedFlagPtr(FakeStack) = 0
3613 // else
3614 // __asan_stack_free_N(FakeStack, LocalStackSize)
3615 // else
3616 // <This is not a fake stack; unpoison the redzones>
3617 Value *Cmp =
3618 IRBRet.CreateICmpNE(FakeStackInt, Constant::getNullValue(IntptrTy));
3619 Instruction *ThenTerm, *ElseTerm;
3620 SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm);
3621
3622 IRBuilder<> IRBPoison(ThenTerm);
3623 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3624 int ClassSize = kMinStackMallocSize << StackMallocIdx;
3625 ShadowAfterReturn.resize(ClassSize / L.Granularity,
3627 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3628 ShadowBase);
3629 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3630 FakeStackPtr,
3631 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3632 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3633 IRBPoison.CreateStore(
3634 Constant::getNullValue(IRBPoison.getInt8Ty()),
3635 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3636 } else {
3637 // For larger frames call __asan_stack_free_*.
3638 RTCI.createRuntimeCall(
3639 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3640 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3641 }
3642
3643 IRBuilder<> IRBElse(ElseTerm);
3644 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3645 } else {
3646 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3647 }
3648 }
3649
3650 // We are done. Remove the old unused alloca instructions.
3651 for (auto *AI : AllocaVec)
3652 AI->eraseFromParent();
3653}
3654
3655void FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size,
3656 IRBuilder<> &IRB, bool DoPoison) {
3657 // For now just insert the call to ASan runtime.
3658 Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy);
3659 Value *SizeArg = ConstantInt::get(IntptrTy, Size);
3660 RTCI.createRuntimeCall(
3661 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3662 {AddrArg, SizeArg});
3663}
3664
3665// Handling llvm.lifetime intrinsics for a given %alloca:
3666// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca.
3667// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect
3668// invalid accesses) and unpoison it for llvm.lifetime.start (the memory
3669// could be poisoned by previous llvm.lifetime.end instruction, as the
3670// variable may go in and out of scope several times, e.g. in loops).
3671// (3) if we poisoned at least one %alloca in a function,
3672// unpoison the whole stack frame at function exit.
3673void FunctionStackPoisoner::handleDynamicAllocaCall(AllocaInst *AI) {
3674 IRBuilder<> IRB(AI);
3675
3676 const Align Alignment = std::max(Align(kAllocaRzSize), AI->getAlign());
3677 const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1;
3678
3679 Value *Zero = Constant::getNullValue(IntptrTy);
3680 Value *AllocaRzSize = ConstantInt::get(IntptrTy, kAllocaRzSize);
3681 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3682
3683 // Since we need to extend alloca with additional memory to locate
3684 // redzones, and OldSize is number of allocated blocks with
3685 // ElementSize size, get allocated memory size in bytes by
3686 // OldSize * ElementSize.
3687 Value *OldSize = IRB.CreateAllocationSize(IntptrTy, AI);
3688
3689 // PartialSize = OldSize % 32
3690 Value *PartialSize = IRB.CreateAnd(OldSize, AllocaRzMask);
3691
3692 // Misalign = kAllocaRzSize - PartialSize;
3693 Value *Misalign = IRB.CreateSub(AllocaRzSize, PartialSize);
3694
3695 // PartialPadding = Misalign != kAllocaRzSize ? Misalign : 0;
3696 Value *Cond = IRB.CreateICmpNE(Misalign, AllocaRzSize);
3697 Value *PartialPadding = IRB.CreateSelect(Cond, Misalign, Zero);
3698
3699 // AdditionalChunkSize = Alignment + PartialPadding + kAllocaRzSize
3700 // Alignment is added to locate left redzone, PartialPadding for possible
3701 // partial redzone and kAllocaRzSize for right redzone respectively.
3702 Value *AdditionalChunkSize = IRB.CreateAdd(
3703 ConstantInt::get(IntptrTy, Alignment.value() + kAllocaRzSize),
3704 PartialPadding);
3705
3706 Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize);
3707
3708 // Insert new alloca with new NewSize and Alignment params.
3709 AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize);
3710 NewAlloca->setAlignment(Alignment);
3711
3712 // NewAddress = Address + Alignment
3713 Value *NewAddress =
3714 IRB.CreateAdd(IRB.CreatePtrToInt(NewAlloca, IntptrTy),
3715 ConstantInt::get(IntptrTy, Alignment.value()));
3716
3717 // Insert __asan_alloca_poison call for new created alloca.
3718 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3719
3720 // Store the last alloca's address to DynamicAllocaLayout. We'll need this
3721 // for unpoisoning stuff.
3722 IRB.CreateStore(IRB.CreatePtrToInt(NewAlloca, IntptrTy), DynamicAllocaLayout);
3723
3724 Value *NewAddressPtr = IRB.CreateIntToPtr(NewAddress, AI->getType());
3725
3726 // Remove lifetime markers now that this is no longer an alloca.
3727 for (User *U : make_early_inc_range(AI->users())) {
3728 auto *I = cast<Instruction>(U);
3729 if (I->isLifetimeStartOrEnd())
3730 I->eraseFromParent();
3731 }
3732
3733 // Replace all uses of AddressReturnedByAlloca with NewAddressPtr.
3734 AI->replaceAllUsesWith(NewAddressPtr);
3735
3736 // We are done. Erase old alloca from parent.
3737 AI->eraseFromParent();
3738}
3739
3740// isSafeAccess returns true if Addr is always inbounds with respect to its
3741// base object. For example, it is a field access or an array access with
3742// constant inbounds index.
3743bool AddressSanitizer::isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
3744 Value *Addr, TypeSize TypeStoreSize) const {
3745 if (TypeStoreSize.isScalable())
3746 // TODO: We can use vscale_range to convert a scalable value to an
3747 // upper bound on the access size.
3748 return false;
3749
3750 SizeOffsetAPInt SizeOffset = ObjSizeVis.compute(Addr);
3751 if (!SizeOffset.bothKnown())
3752 return false;
3753
3754 uint64_t Size = SizeOffset.Size.getZExtValue();
3755 int64_t Offset = SizeOffset.Offset.getSExtValue();
3756
3757 // Three checks are required to ensure safety:
3758 // . Offset >= 0 (since the offset is given from the base ptr)
3759 // . Size >= Offset (unsigned)
3760 // . Size - Offset >= NeededSize (unsigned)
3761 return Offset >= 0 && Size >= uint64_t(Offset) &&
3762 Size - uint64_t(Offset) >= TypeStoreSize / 8;
3763}
const TargetLowering & TLI
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:550
#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:854
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:899
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:2324
Value * CreatePtrAddWithUnsignedOffset(Value *Ptr, uint64_t Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Create a ptradd with an unsigned constant offset.
Definition IRBuilder.h:2113
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1886
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:513
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:2733
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1940
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition IRBuilder.h:2215
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:657
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2373
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2486
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:177
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2314
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1534
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:528
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2094
BasicBlock * GetInsertBlock() const
Definition IRBuilder.h:174
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:533
LLVM_ABI Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2462
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:471
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2623
Value * CreateNot(Value *V, const Twine &Name="")
Definition IRBuilder.h:1856
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2458
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1441
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
Definition IRBuilder.h:481
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:1913
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1572
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:1931
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1424
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2309
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition IRBuilder.h:2839
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2637
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:2399
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:197
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:566
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1959
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1594
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:518
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1458
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2987
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.
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:1002
bool isDriverKit() const
Is this an Apple DriverKit triple.
Definition Triple.h:709
bool isBPF() const
Tests whether the target is eBPF.
Definition Triple.h:1244
bool isOSNetBSD() const
Definition Triple.h:746
bool isAndroid() const
Tests whether the target is Android.
Definition Triple.h:912
bool isABIN32() const
Definition Triple.h:1232
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition Triple.h:1134
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:516
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition Triple.h:1123
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
Definition Triple.h:1129
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:779
@ UnknownObjectFormat
Definition Triple.h:423
bool isARM() const
Tests whether the target is ARM (little and big endian).
Definition Triple.h:1007
bool isOSLinux() const
Tests whether the OS is Linux.
Definition Triple.h:832
bool isAMDGPU() const
Definition Triple.h:999
bool isMacOSX() const
Is this a Mac OS X triple.
Definition Triple.h:683
bool isOSFreeBSD() const
Definition Triple.h:750
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition Triple.h:847
bool isWatchOS() const
Is this an Apple watchOS triple.
Definition Triple.h:698
bool isiOS() const
Is this an iOS triple.
Definition Triple.h:692
bool isPS() const
Tests whether the target is the PS4 or PS5 platform.
Definition Triple.h:909
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Definition Triple.h:1213
bool isOSFuchsia() const
Definition Triple.h:752
bool isOSHaiku() const
Tests whether the OS is Haiku.
Definition Triple.h:773
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
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:512
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:548
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:1144
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:395
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:3954
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:2012
#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.