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