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