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
1696static bool isPointerPairOperand(Value *V, Type *IntptrTy) {
1697 Type *Ty = V->getType();
1698 if (Ty->isPtrOrPtrVectorTy())
1699 return true;
1700 return Ty->isIntOrIntVectorTy() &&
1701 Ty->getScalarSizeInBits() == IntptrTy->getScalarSizeInBits();
1702}
1703
1704bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1705 Instruction *I, RuntimeCallInserter &RTCI) {
1706 Value *Param[2] = {I->getOperand(0), I->getOperand(1)};
1707 if (!isPointerPairOperand(Param[0], IntptrTy) ||
1708 !isPointerPairOperand(Param[1], IntptrTy))
1709 return false;
1710
1711 IRBuilder<> IRB(I);
1712 FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
1713
1714 if (const auto *Ty = Param[0]->getType(); Ty->isVectorTy()) {
1715 const auto *VTy = dyn_cast<FixedVectorType>(Ty);
1716 // TODO: Add support for scalable vectors if possible.
1717 if (!VTy)
1718 return false;
1719
1720 assert(Param[0]->getType() == Param[1]->getType() &&
1721 "invalid vector pointer pair instrumentation operands");
1722 for (unsigned Index = 0, NumElements = VTy->getNumElements();
1723 Index != NumElements; ++Index) {
1724 Value *ScalarParam[2] = {
1726 IRB.CreateExtractElement(Param[0], IRB.getInt32(Index)),
1727 IntptrTy),
1729 IRB.CreateExtractElement(Param[1], IRB.getInt32(Index)),
1730 IntptrTy)};
1731 RTCI.createRuntimeCall(IRB, F, ScalarParam);
1732 }
1733 return true;
1734 }
1735
1736 for (Value *&P : Param)
1737 P = IRB.CreatePointerCast(P, IntptrTy);
1738 RTCI.createRuntimeCall(IRB, F, Param);
1739 return true;
1740}
1741
1742static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
1743 Instruction *InsertBefore, Value *Addr,
1744 MaybeAlign Alignment, unsigned Granularity,
1745 TypeSize TypeStoreSize, bool IsWrite,
1746 Value *SizeArgument, bool UseCalls,
1747 uint32_t Exp, RuntimeCallInserter &RTCI) {
1748 // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
1749 // if the data is properly aligned.
1750 if (!TypeStoreSize.isScalable()) {
1751 const auto FixedSize = TypeStoreSize.getFixedValue();
1752 switch (FixedSize) {
1753 case 8:
1754 case 16:
1755 case 32:
1756 case 64:
1757 case 128:
1758 if (!Alignment || *Alignment >= Granularity ||
1759 *Alignment >= FixedSize / 8)
1760 return Pass->instrumentAddress(I, InsertBefore, Addr, Alignment,
1761 FixedSize, IsWrite, nullptr, UseCalls,
1762 Exp, RTCI);
1763 }
1764 }
1765 Pass->instrumentUnusualSizeOrAlignment(I, InsertBefore, Addr, TypeStoreSize,
1766 IsWrite, nullptr, UseCalls, Exp, RTCI);
1767}
1768
1769void AddressSanitizer::instrumentMaskedLoadOrStore(
1770 AddressSanitizer *Pass, const DataLayout &DL, Type *IntptrTy, Value *Mask,
1771 Value *EVL, Value *Stride, Instruction *I, Value *Addr,
1772 MaybeAlign Alignment, unsigned Granularity, Type *OpType, bool IsWrite,
1773 Value *SizeArgument, bool UseCalls, uint32_t Exp,
1774 RuntimeCallInserter &RTCI) {
1775 auto *VTy = cast<VectorType>(OpType);
1776 TypeSize ElemTypeSize = DL.getTypeStoreSizeInBits(VTy->getScalarType());
1777 auto Zero = ConstantInt::get(IntptrTy, 0);
1778
1779 IRBuilder IB(I);
1780 Instruction *LoopInsertBefore = I;
1781 if (EVL) {
1782 // The end argument of SplitBlockAndInsertForLane is assumed bigger
1783 // than zero, so we should check whether EVL is zero here.
1784 Type *EVLType = EVL->getType();
1785 Value *IsEVLZero = IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1786 LoopInsertBefore = SplitBlockAndInsertIfThen(IsEVLZero, I, false);
1787 IB.SetInsertPoint(LoopInsertBefore);
1788 // Cast EVL to IntptrTy.
1789 EVL = IB.CreateZExtOrTrunc(EVL, IntptrTy);
1790 // To avoid undefined behavior for extracting with out of range index, use
1791 // the minimum of evl and element count as trip count.
1792 Value *EC = IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1793 EVL = IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1794 } else {
1795 EVL = IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1796 }
1797
1798 // Cast Stride to IntptrTy.
1799 if (Stride)
1800 Stride = IB.CreateZExtOrTrunc(Stride, IntptrTy);
1801
1802 SplitBlockAndInsertForEachLane(EVL, LoopInsertBefore->getIterator(),
1803 [&](IRBuilderBase &IRB, Value *Index) {
1804 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1805 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1806 if (MaskElemC->isZero())
1807 // No check
1808 return;
1809 // Unconditional check
1810 } else {
1811 // Conditional check
1812 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1813 MaskElem, &*IRB.GetInsertPoint(), false);
1814 IRB.SetInsertPoint(ThenTerm);
1815 }
1816
1817 Value *InstrumentedAddress;
1818 if (isa<VectorType>(Addr->getType())) {
1819 assert(
1820 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1821 "Expected vector of pointer.");
1822 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1823 } else if (Stride) {
1824 Index = IRB.CreateMul(Index, Stride);
1825 InstrumentedAddress = IRB.CreatePtrAdd(Addr, Index);
1826 } else {
1827 InstrumentedAddress = IRB.CreateGEP(VTy, Addr, {Zero, Index});
1828 }
1829 doInstrumentAddress(Pass, I, &*IRB.GetInsertPoint(), InstrumentedAddress,
1830 Alignment, Granularity, ElemTypeSize, IsWrite,
1831 SizeArgument, UseCalls, Exp, RTCI);
1832 });
1833}
1834
1835void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
1836 InterestingMemoryOperand &O, bool UseCalls,
1837 const DataLayout &DL,
1838 RuntimeCallInserter &RTCI) {
1839 Value *Addr = O.getPtr();
1840
1841 // Optimization experiments.
1842 // The experiments can be used to evaluate potential optimizations that remove
1843 // instrumentation (assess false negatives). Instead of completely removing
1844 // some instrumentation, you set Exp to a non-zero value (mask of optimization
1845 // experiments that want to remove instrumentation of this instruction).
1846 // If Exp is non-zero, this pass will emit special calls into runtime
1847 // (e.g. __asan_report_exp_load1 instead of __asan_report_load1). These calls
1848 // make runtime terminate the program in a special way (with a different
1849 // exit status). Then you run the new compiler on a buggy corpus, collect
1850 // the special terminations (ideally, you don't see them at all -- no false
1851 // negatives) and make the decision on the optimization.
1852 uint32_t Exp = ClForceExperiment;
1853
1854 if (ClOpt && ClOptGlobals) {
1855 // If initialization order checking is disabled, a simple access to a
1856 // dynamically initialized global is always valid.
1858 if (G && (!ClInitializers || GlobalIsLinkerInitialized(G)) &&
1859 isSafeAccess(ObjSizeVis, Addr, O.TypeStoreSize)) {
1860 NumOptimizedAccessesToGlobalVar++;
1861 return;
1862 }
1863 }
1864
1865 if (ClOpt && ClOptStack) {
1866 // A direct inbounds access to a stack variable is always valid.
1868 isSafeAccess(ObjSizeVis, Addr, O.TypeStoreSize)) {
1869 NumOptimizedAccessesToStackVar++;
1870 return;
1871 }
1872 }
1873
1874 if (O.IsWrite)
1875 NumInstrumentedWrites++;
1876 else
1877 NumInstrumentedReads++;
1878
1879 if (O.MaybeByteOffset) {
1880 Type *Ty = Type::getInt8Ty(*C);
1881 IRBuilder IB(O.getInsn());
1882
1883 Value *OffsetOp = O.MaybeByteOffset;
1884 if (TargetTriple.isRISCV()) {
1885 Type *OffsetTy = OffsetOp->getType();
1886 // RVV indexed loads/stores zero-extend offset operands which are narrower
1887 // than XLEN to XLEN.
1888 if (OffsetTy->getScalarType()->getIntegerBitWidth() <
1889 static_cast<unsigned>(LongSize)) {
1890 VectorType *OrigType = cast<VectorType>(OffsetTy);
1891 Type *ExtendTy = VectorType::get(IntptrTy, OrigType);
1892 OffsetOp = IB.CreateZExt(OffsetOp, ExtendTy);
1893 }
1894 }
1895 Addr = IB.CreateGEP(Ty, Addr, {OffsetOp});
1896 }
1897
1898 unsigned Granularity = 1 << Mapping.Scale;
1899 if (O.MaybeMask) {
1900 instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.MaybeEVL,
1901 O.MaybeStride, O.getInsn(), Addr, O.Alignment,
1902 Granularity, O.OpType, O.IsWrite, nullptr,
1903 UseCalls, Exp, RTCI);
1904 } else {
1905 doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment,
1906 Granularity, O.TypeStoreSize, O.IsWrite, nullptr,
1907 UseCalls, Exp, RTCI);
1908 }
1909}
1910
1911Instruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore,
1912 Value *Addr, bool IsWrite,
1913 size_t AccessSizeIndex,
1914 Value *SizeArgument,
1915 uint32_t Exp,
1916 RuntimeCallInserter &RTCI) {
1917 InstrumentationIRBuilder IRB(InsertBefore);
1918 Value *ExpVal = Exp == 0 ? nullptr : ConstantInt::get(IRB.getInt32Ty(), Exp);
1919 CallInst *Call = nullptr;
1920 if (SizeArgument) {
1921 if (Exp == 0)
1922 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1923 {Addr, SizeArgument});
1924 else
1925 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1926 {Addr, SizeArgument, ExpVal});
1927 } else {
1928 if (Exp == 0)
1929 Call = RTCI.createRuntimeCall(
1930 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1931 else
1932 Call = RTCI.createRuntimeCall(
1933 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1934 }
1935
1937 return Call;
1938}
1939
1940Value *AddressSanitizer::createSlowPathCmp(IRBuilder<> &IRB, Value *AddrLong,
1941 Value *ShadowValue,
1942 uint32_t TypeStoreSize) {
1943 size_t Granularity = static_cast<size_t>(1) << Mapping.Scale;
1944 // Addr & (Granularity - 1)
1945 Value *LastAccessedByte =
1946 IRB.CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1947 // (Addr & (Granularity - 1)) + size - 1
1948 if (TypeStoreSize / 8 > 1)
1949 LastAccessedByte = IRB.CreateAdd(
1950 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1951 // (uint8_t) ((Addr & (Granularity-1)) + size - 1)
1952 LastAccessedByte =
1953 IRB.CreateIntCast(LastAccessedByte, ShadowValue->getType(), false);
1954 // ((uint8_t) ((Addr & (Granularity-1)) + size - 1)) >= ShadowValue
1955 return IRB.CreateICmpSGE(LastAccessedByte, ShadowValue);
1956}
1957
1958Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1959 Instruction *OrigIns, Instruction *InsertBefore, Value *Addr,
1960 uint32_t TypeStoreSize, bool IsWrite, Value *SizeArgument) {
1961 // Do not instrument unsupported addrspaces.
1963 return nullptr;
1964 Type *PtrTy = cast<PointerType>(Addr->getType()->getScalarType());
1965 // Follow host instrumentation for global and constant addresses.
1966 if (PtrTy->getPointerAddressSpace() != 0)
1967 return InsertBefore;
1968 // Instrument generic addresses in supported addressspaces.
1969 IRBuilder<> IRB(InsertBefore);
1970 Value *IsShared = IRB.CreateCall(AMDGPUAddressShared, {Addr});
1971 Value *IsPrivate = IRB.CreateCall(AMDGPUAddressPrivate, {Addr});
1972 Value *IsSharedOrPrivate = IRB.CreateOr(IsShared, IsPrivate);
1973 Value *Cmp = IRB.CreateNot(IsSharedOrPrivate);
1974 Value *AddrSpaceZeroLanding =
1975 SplitBlockAndInsertIfThen(Cmp, InsertBefore, false);
1976 InsertBefore = cast<Instruction>(AddrSpaceZeroLanding);
1977 return InsertBefore;
1978}
1979
1980Instruction *AddressSanitizer::genAMDGPUReportBlock(IRBuilder<> &IRB,
1981 Value *Cond, bool Recover) {
1982 Value *ReportCond = Cond;
1983 if (!Recover) {
1984 auto Ballot = Inserter.insertFunction(kAMDGPUBallotName, IRB.getInt64Ty(),
1985 IRB.getInt1Ty());
1986 ReportCond = IRB.CreateIsNotNull(IRB.CreateCall(Ballot, {Cond}));
1987 }
1988
1989 auto *Trm =
1990 SplitBlockAndInsertIfThen(ReportCond, &*IRB.GetInsertPoint(), false,
1992 Trm->getParent()->setName("asan.report");
1993
1994 if (Recover)
1995 return Trm;
1996
1997 Trm = SplitBlockAndInsertIfThen(Cond, Trm, false);
1998 IRB.SetInsertPoint(Trm);
1999 return IRB.CreateCall(
2000 Inserter.insertFunction(kAMDGPUUnreachableName, IRB.getVoidTy()), {});
2001}
2002
2003void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
2004 Instruction *InsertBefore, Value *Addr,
2005 MaybeAlign Alignment,
2006 uint32_t TypeStoreSize, bool IsWrite,
2007 Value *SizeArgument, bool UseCalls,
2008 uint32_t Exp,
2009 RuntimeCallInserter &RTCI) {
2010 if (TargetTriple.isAMDGPU()) {
2011 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
2012 TypeStoreSize, IsWrite, SizeArgument);
2013 if (!InsertBefore)
2014 return;
2015 }
2016
2017 InstrumentationIRBuilder IRB(InsertBefore);
2018 size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
2019
2020 if (UseCalls && ClOptimizeCallbacks) {
2021 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
2022 IRB.CreateIntrinsic(Intrinsic::asan_check_memaccess, {},
2023 {IRB.CreatePointerCast(Addr, PtrTy),
2024 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
2025 return;
2026 }
2027
2028 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
2029 if (UseCalls) {
2030 if (Exp == 0)
2031 RTCI.createRuntimeCall(
2032 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
2033 else
2034 RTCI.createRuntimeCall(
2035 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
2036 {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)});
2037 return;
2038 }
2039
2040 Type *ShadowTy =
2041 IntegerType::get(*C, std::max(8U, TypeStoreSize >> Mapping.Scale));
2042 Type *ShadowPtrTy = PointerType::get(*C, ClShadowAddrSpace);
2043 Value *ShadowPtr = memToShadow(AddrLong, IRB);
2044 const uint64_t ShadowAlign =
2045 std::max<uint64_t>(Alignment.valueOrOne().value() >> Mapping.Scale, 1);
2046 Value *ShadowValue = IRB.CreateAlignedLoad(
2047 ShadowTy, IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy), Align(ShadowAlign));
2048
2049 Value *Cmp = IRB.CreateIsNotNull(ShadowValue);
2050 size_t Granularity = 1ULL << Mapping.Scale;
2051 Instruction *CrashTerm = nullptr;
2052
2053 bool GenSlowPath = (ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
2054
2055 if (TargetTriple.isAMDGCN()) {
2056 if (GenSlowPath) {
2057 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2058 Cmp = IRB.CreateAnd(Cmp, Cmp2);
2059 }
2060 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2061 } else if (GenSlowPath) {
2062 // We use branch weights for the slow path check, to indicate that the slow
2063 // path is rarely taken. This seems to be the case for SPEC benchmarks.
2065 Cmp, InsertBefore, false, MDBuilder(*C).createUnlikelyBranchWeights());
2066 BasicBlock *NextBB = cast<UncondBrInst>(CheckTerm)->getSuccessor();
2067 IRB.SetInsertPoint(CheckTerm);
2068 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2069 if (Recover) {
2070 CrashTerm = SplitBlockAndInsertIfThen(Cmp2, CheckTerm, false);
2071 } else {
2072 BasicBlock *CrashBlock =
2073 BasicBlock::Create(*C, "", NextBB->getParent(), NextBB);
2074 CrashTerm = new UnreachableInst(*C, CrashBlock);
2075 CondBrInst *NewTerm = CondBrInst::Create(Cmp2, CrashBlock, NextBB);
2076 ReplaceInstWithInst(CheckTerm, NewTerm);
2077 }
2078 } else {
2079 CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, !Recover);
2080 }
2081
2082 Instruction *Crash = generateCrashCode(
2083 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2084 if (OrigIns->getDebugLoc())
2085 Crash->setDebugLoc(OrigIns->getDebugLoc());
2086}
2087
2088// Instrument unusual size or unusual alignment.
2089// We can not do it with a single check, so we do 1-byte check for the first
2090// and the last bytes. We call __asan_report_*_n(addr, real_size) to be able
2091// to report the actual access size.
2092void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2093 Instruction *I, Instruction *InsertBefore, Value *Addr,
2094 TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls,
2095 uint32_t Exp, RuntimeCallInserter &RTCI) {
2096 InstrumentationIRBuilder IRB(InsertBefore);
2097 Value *NumBits = IRB.CreateTypeSize(IntptrTy, TypeStoreSize);
2098 Value *Size = IRB.CreateLShr(NumBits, ConstantInt::get(IntptrTy, 3));
2099
2100 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
2101 if (UseCalls) {
2102 if (Exp == 0)
2103 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2104 {AddrLong, Size});
2105 else
2106 RTCI.createRuntimeCall(
2107 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2108 {AddrLong, Size, ConstantInt::get(IRB.getInt32Ty(), Exp)});
2109 } else {
2110 Value *SizeMinusOne = IRB.CreateSub(Size, ConstantInt::get(IntptrTy, 1));
2111 Value *LastByte = IRB.CreateIntToPtr(
2112 IRB.CreateAdd(AddrLong, SizeMinusOne),
2113 Addr->getType());
2114 instrumentAddress(I, InsertBefore, Addr, {}, 8, IsWrite, Size, false, Exp,
2115 RTCI);
2116 instrumentAddress(I, InsertBefore, LastByte, {}, 8, IsWrite, Size, false,
2117 Exp, RTCI);
2118 }
2119}
2120
2121void ModuleAddressSanitizer::poisonOneInitializer(Function &GlobalInit) {
2122 // Set up the arguments to our poison/unpoison functions.
2123 IRBuilder<> IRB(&GlobalInit.front(),
2124 GlobalInit.front().getFirstInsertionPt());
2125
2126 // Add a call to poison all external globals before the given function starts.
2127 Value *ModuleNameAddr =
2128 ConstantExpr::getPointerCast(getOrCreateModuleName(), IntptrTy);
2129 CallInst *CallBefore = IRB.CreateCall(AsanPoisonGlobals, ModuleNameAddr);
2130 if (DISubprogram *SP = GlobalInit.getSubprogram())
2131 CallBefore->setDebugLoc(
2132 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
2133
2134 // Add calls to unpoison all globals before each return instruction.
2135 for (auto &BB : GlobalInit)
2137 CallInst *CallAfter =
2138 CallInst::Create(AsanUnpoisonGlobals, "", RI->getIterator());
2139 if (RI->getDebugLoc())
2140 CallAfter->setDebugLoc(RI->getDebugLoc());
2141 else if (DISubprogram *SP = GlobalInit.getSubprogram())
2142 CallAfter->setDebugLoc(
2143 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
2144 }
2145}
2146
2147void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2148 GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
2149 if (!GV)
2150 return;
2151
2153 if (!CA)
2154 return;
2155
2156 for (Use &OP : CA->operands()) {
2157 if (isa<ConstantAggregateZero>(OP)) continue;
2159
2160 // Must have a function or null ptr.
2161 if (Function *F = dyn_cast<Function>(CS->getOperand(1))) {
2162 if (F->getName() == kAsanModuleCtorName) continue;
2163 auto *Priority = cast<ConstantInt>(CS->getOperand(0));
2164 // Don't instrument CTORs that will run before asan.module_ctor.
2165 if (Priority->getLimitedValue() <= GetCtorAndDtorPriority(TargetTriple))
2166 continue;
2167 poisonOneInitializer(*F);
2168 }
2169 }
2170}
2171
2172const GlobalVariable *
2173ModuleAddressSanitizer::getExcludedAliasedGlobal(const GlobalAlias &GA) const {
2174 // In case this function should be expanded to include rules that do not just
2175 // apply when CompileKernel is true, either guard all existing rules with an
2176 // 'if (CompileKernel) { ... }' or be absolutely sure that all these rules
2177 // should also apply to user space.
2178 assert(CompileKernel && "Only expecting to be called when compiling kernel");
2179
2180 const Constant *C = GA.getAliasee();
2181
2182 // When compiling the kernel, globals that are aliased by symbols prefixed
2183 // by "__" are special and cannot be padded with a redzone.
2184 if (GA.getName().starts_with("__"))
2185 return dyn_cast<GlobalVariable>(C->stripPointerCastsAndAliases());
2186
2187 return nullptr;
2188}
2189
2190bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
2191 Type *Ty = G->getValueType();
2192 LLVM_DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
2193
2194 if (G->hasSanitizerMetadata() && G->getSanitizerMetadata().NoAddress)
2195 return false;
2196 if (!Ty->isSized()) return false;
2197 if (!G->hasInitializer()) return false;
2198 if (!isSupportedAddrspace(TargetTriple, G))
2199 return false;
2200 if (GlobalWasGeneratedByCompiler(G)) return false; // Our own globals.
2201 // Two problems with thread-locals:
2202 // - The address of the main thread's copy can't be computed at link-time.
2203 // - Need to poison all copies, not just the main thread's one.
2204 if (G->isThreadLocal()) return false;
2205 // For now, just ignore this Global if the alignment is large.
2206 if (G->getAlign() && *G->getAlign() > getMinRedzoneSizeForGlobal()) return false;
2207
2208 // For non-COFF targets, only instrument globals known to be defined by this
2209 // TU.
2210 // FIXME: We can instrument comdat globals on ELF if we are using the
2211 // GC-friendly metadata scheme.
2212 if (!TargetTriple.isOSBinFormatCOFF()) {
2213 if (!G->hasExactDefinition() || G->hasComdat())
2214 return false;
2215 } else {
2216 // On COFF, don't instrument non-ODR linkages.
2217 if (G->isInterposable())
2218 return false;
2219 // If the global has AvailableExternally linkage, then it is not in this
2220 // module, which means it does not need to be instrumented.
2221 if (G->hasAvailableExternallyLinkage())
2222 return false;
2223 }
2224
2225 // If a comdat is present, it must have a selection kind that implies ODR
2226 // semantics: no duplicates, any, or exact match.
2227 if (Comdat *C = G->getComdat()) {
2228 switch (C->getSelectionKind()) {
2229 case Comdat::Any:
2230 case Comdat::ExactMatch:
2232 break;
2233 case Comdat::Largest:
2234 case Comdat::SameSize:
2235 return false;
2236 }
2237 }
2238
2239 if (G->hasSection()) {
2240 // The kernel uses explicit sections for mostly special global variables
2241 // that we should not instrument. E.g. the kernel may rely on their layout
2242 // without redzones, or remove them at link time ("discard.*"), etc.
2243 if (CompileKernel)
2244 return false;
2245
2246 StringRef Section = G->getSection();
2247
2248 // Globals from llvm.metadata aren't emitted, do not instrument them.
2249 if (Section == "llvm.metadata") return false;
2250 // Do not instrument globals from special LLVM sections.
2251 if (Section.contains("__llvm") || Section.contains("__LLVM"))
2252 return false;
2253
2254 // Do not instrument function pointers to initialization and termination
2255 // routines: dynamic linker will not properly handle redzones.
2256 if (Section.starts_with(".preinit_array") ||
2257 Section.starts_with(".init_array") ||
2258 Section.starts_with(".fini_array")) {
2259 return false;
2260 }
2261
2262 // Do not instrument user-defined sections (with names resembling
2263 // valid C identifiers)
2264 if (TargetTriple.isOSBinFormatELF()) {
2265 if (llvm::all_of(Section,
2266 [](char c) { return llvm::isAlnum(c) || c == '_'; }))
2267 return false;
2268 }
2269
2270 // On COFF, if the section name contains '$', it is highly likely that the
2271 // user is using section sorting to create an array of globals similar to
2272 // the way initialization callbacks are registered in .init_array and
2273 // .CRT$XCU. The ATL also registers things in .ATL$__[azm]. Adding redzones
2274 // to such globals is counterproductive, because the intent is that they
2275 // will form an array, and out-of-bounds accesses are expected.
2276 // See https://github.com/google/sanitizers/issues/305
2277 // and http://msdn.microsoft.com/en-US/en-en/library/bb918180(v=vs.120).aspx
2278 if (TargetTriple.isOSBinFormatCOFF() && Section.contains('$')) {
2279 LLVM_DEBUG(dbgs() << "Ignoring global in sorted section (contains '$'): "
2280 << *G << "\n");
2281 return false;
2282 }
2283
2284 if (TargetTriple.isOSBinFormatMachO()) {
2285 StringRef ParsedSegment, ParsedSection;
2286 unsigned TAA = 0, StubSize = 0;
2287 bool TAAParsed;
2289 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2290
2291 // Ignore the globals from the __OBJC section. The ObjC runtime assumes
2292 // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to
2293 // them.
2294 if (ParsedSegment == "__OBJC" ||
2295 (ParsedSegment == "__DATA" && ParsedSection.starts_with("__objc_"))) {
2296 LLVM_DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G << "\n");
2297 return false;
2298 }
2299 // See https://github.com/google/sanitizers/issues/32
2300 // Constant CFString instances are compiled in the following way:
2301 // -- the string buffer is emitted into
2302 // __TEXT,__cstring,cstring_literals
2303 // -- the constant NSConstantString structure referencing that buffer
2304 // is placed into __DATA,__cfstring
2305 // Therefore there's no point in placing redzones into __DATA,__cfstring.
2306 // Moreover, it causes the linker to crash on OS X 10.7
2307 if (ParsedSegment == "__DATA" && ParsedSection == "__cfstring") {
2308 LLVM_DEBUG(dbgs() << "Ignoring CFString: " << *G << "\n");
2309 return false;
2310 }
2311 // The linker merges the contents of cstring_literals and removes the
2312 // trailing zeroes.
2313 if (ParsedSegment == "__TEXT" && (TAA & MachO::S_CSTRING_LITERALS)) {
2314 LLVM_DEBUG(dbgs() << "Ignoring a cstring literal: " << *G << "\n");
2315 return false;
2316 }
2317 }
2318 }
2319
2320 if (CompileKernel) {
2321 // Globals that prefixed by "__" are special and cannot be padded with a
2322 // redzone.
2323 if (G->getName().starts_with("__"))
2324 return false;
2325 }
2326
2327 return true;
2328}
2329
2330// On Mach-O platforms, we emit global metadata in a separate section of the
2331// binary in order to allow the linker to properly dead strip. This is only
2332// supported on recent versions of ld64.
2333bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection() const {
2334 if (!TargetTriple.isOSBinFormatMachO())
2335 return false;
2336
2337 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2338 return true;
2339 if (TargetTriple.isiOS() /* or tvOS */ && !TargetTriple.isOSVersionLT(9))
2340 return true;
2341 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2342 return true;
2343 if (TargetTriple.isDriverKit())
2344 return true;
2345 if (TargetTriple.isXROS())
2346 return true;
2347
2348 return false;
2349}
2350
2351StringRef ModuleAddressSanitizer::getGlobalMetadataSection() const {
2352 switch (TargetTriple.getObjectFormat()) {
2353 case Triple::COFF: return ".ASAN$GL";
2354 case Triple::ELF: return "asan_globals";
2355 case Triple::MachO: return "__DATA,__asan_globals,regular";
2356 case Triple::Wasm:
2357 case Triple::GOFF:
2358 case Triple::SPIRV:
2359 case Triple::XCOFF:
2362 "ModuleAddressSanitizer not implemented for object file format");
2364 break;
2365 }
2366 llvm_unreachable("unsupported object format");
2367}
2368
2369void ModuleAddressSanitizer::initializeCallbacks() {
2370 IRBuilder<> IRB(*C);
2371
2372 // Declare our poisoning and unpoisoning functions.
2373 AsanPoisonGlobals = Inserter.insertFunction(kAsanPoisonGlobalsName,
2374 IRB.getVoidTy(), IntptrTy);
2375 AsanUnpoisonGlobals =
2376 Inserter.insertFunction(kAsanUnpoisonGlobalsName, IRB.getVoidTy());
2377
2378 // Declare functions that register/unregister globals.
2379 AsanRegisterGlobals = Inserter.insertFunction(
2380 kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy);
2381 AsanUnregisterGlobals = Inserter.insertFunction(
2382 kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy);
2383
2384 // Declare the functions that find globals in a shared object and then invoke
2385 // the (un)register function on them.
2386 AsanRegisterImageGlobals = Inserter.insertFunction(
2387 kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy);
2388 AsanUnregisterImageGlobals = Inserter.insertFunction(
2390
2391 AsanRegisterElfGlobals =
2392 Inserter.insertFunction(kAsanRegisterElfGlobalsName, IRB.getVoidTy(),
2393 IntptrTy, IntptrTy, IntptrTy);
2394 AsanUnregisterElfGlobals =
2395 Inserter.insertFunction(kAsanUnregisterElfGlobalsName, IRB.getVoidTy(),
2396 IntptrTy, IntptrTy, IntptrTy);
2397}
2398
2399// Put the metadata and the instrumented global in the same group. This ensures
2400// that the metadata is discarded if the instrumented global is discarded.
2401void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2402 GlobalVariable *G, GlobalVariable *Metadata, StringRef InternalSuffix) {
2403 Module &M = *G->getParent();
2404 Comdat *C = G->getComdat();
2405 if (!C) {
2406 if (!G->hasName()) {
2407 // If G is unnamed, it must be internal. Give it an artificial name
2408 // so we can put it in a comdat.
2409 assert(G->hasLocalLinkage());
2410 G->setName(genName("anon_global"));
2411 }
2412
2413 if (!InternalSuffix.empty() && G->hasLocalLinkage()) {
2414 std::string Name = std::string(G->getName());
2415 Name += InternalSuffix;
2416 C = M.getOrInsertComdat(Name);
2417 } else {
2418 C = M.getOrInsertComdat(G->getName());
2419 }
2420
2421 // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. Also upgrade private
2422 // linkage to internal linkage so that a symbol table entry is emitted. This
2423 // is necessary in order to create the comdat group.
2424 if (TargetTriple.isOSBinFormatCOFF()) {
2425 C->setSelectionKind(Comdat::NoDeduplicate);
2426 if (G->hasPrivateLinkage())
2427 G->setLinkage(GlobalValue::InternalLinkage);
2428 }
2429 G->setComdat(C);
2430 }
2431
2432 assert(G->hasComdat());
2433 Metadata->setComdat(G->getComdat());
2434}
2435
2436// Create a separate metadata global and put it in the appropriate ASan
2437// global registration section.
2439ModuleAddressSanitizer::CreateMetadataGlobal(Constant *Initializer,
2440 StringRef OriginalName) {
2441 auto Linkage = TargetTriple.isOSBinFormatMachO()
2445 M, Initializer->getType(), false, Linkage, Initializer,
2446 Twine("__asan_global_") + GlobalValue::dropLLVMManglingEscape(OriginalName));
2447 Metadata->setSection(getGlobalMetadataSection());
2448 // Place metadata in a large section for x86-64 ELF binaries to mitigate
2449 // relocation pressure.
2451 return Metadata;
2452}
2453
2454Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2455 AsanDtorFunction = Function::createWithDefaultAttr(
2458 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2459 // Ensure Dtor cannot be discarded, even if in a comdat.
2460 appendToUsed(M, {AsanDtorFunction});
2461 BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
2462
2463 return ReturnInst::Create(*C, AsanDtorBB);
2464}
2465
2466void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2467 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2468 ArrayRef<Constant *> MetadataInitializers) {
2469 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2470 auto &DL = M.getDataLayout();
2471
2472 SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
2473 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2474 Constant *Initializer = MetadataInitializers[i];
2475 GlobalVariable *G = ExtendedGlobals[i];
2476 GlobalVariable *Metadata = CreateMetadataGlobal(Initializer, G->getName());
2477 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
2478 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2479 MetadataGlobals[i] = Metadata;
2480
2481 // The MSVC linker always inserts padding when linking incrementally. We
2482 // cope with that by aligning each struct to its size, which must be a power
2483 // of two.
2484 unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
2485 assert(isPowerOf2_32(SizeOfGlobalStruct) &&
2486 "global metadata will not be padded appropriately");
2487 Metadata->setAlignment(assumeAligned(SizeOfGlobalStruct));
2488
2489 SetComdatForGlobalMetadata(G, Metadata, "");
2490 }
2491
2492 // Update llvm.compiler.used, adding the new metadata globals. This is
2493 // needed so that during LTO these variables stay alive.
2494 if (!MetadataGlobals.empty())
2495 appendToCompilerUsed(M, MetadataGlobals);
2496}
2497
2498void ModuleAddressSanitizer::instrumentGlobalsELF(
2499 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2500 ArrayRef<Constant *> MetadataInitializers,
2501 const std::string &UniqueModuleId) {
2502 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2503
2504 // Putting globals in a comdat changes the semantic and potentially cause
2505 // false negative odr violations at link time. If odr indicators are used, we
2506 // keep the comdat sections, as link time odr violations will be detected on
2507 // the odr indicator symbols.
2508 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2509
2510 SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
2511 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2512 GlobalVariable *G = ExtendedGlobals[i];
2514 CreateMetadataGlobal(MetadataInitializers[i], G->getName());
2515 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
2516 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2517 MetadataGlobals[i] = Metadata;
2518
2519 if (UseComdatForGlobalsGC)
2520 SetComdatForGlobalMetadata(G, Metadata, UniqueModuleId);
2521 }
2522
2523 // Update llvm.compiler.used, adding the new metadata globals. This is
2524 // needed so that during LTO these variables stay alive.
2525 if (!MetadataGlobals.empty())
2526 appendToCompilerUsed(M, MetadataGlobals);
2527
2528 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
2529 // to look up the loaded image that contains it. Second, we can store in it
2530 // whether registration has already occurred, to prevent duplicate
2531 // registration.
2532 //
2533 // Common linkage ensures that there is only one global per shared library.
2534 GlobalVariable *RegisteredFlag = new GlobalVariable(
2535 M, IntptrTy, false, GlobalVariable::CommonLinkage,
2536 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
2538
2539 // Create start and stop symbols.
2540 GlobalVariable *StartELFMetadata = new GlobalVariable(
2541 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2542 "__start_" + getGlobalMetadataSection());
2544 GlobalVariable *StopELFMetadata = new GlobalVariable(
2545 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2546 "__stop_" + getGlobalMetadataSection());
2548
2549 // Create a call to register the globals with the runtime.
2550 if (ConstructorKind == AsanCtorKind::Global)
2551 IRB.CreateCall(AsanRegisterElfGlobals,
2552 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
2553 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
2554 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
2555
2556 // We also need to unregister globals at the end, e.g., when a shared library
2557 // gets closed.
2558 if (DestructorKind != AsanDtorKind::None && !MetadataGlobals.empty()) {
2559 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2560 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2561 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
2562 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
2563 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
2564 }
2565}
2566
2567void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2568 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2569 ArrayRef<Constant *> MetadataInitializers) {
2570 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2571
2572 // On recent Mach-O platforms, use a structure which binds the liveness of
2573 // the global variable to the metadata struct. Keep the list of "Liveness" GV
2574 // created to be added to llvm.compiler.used
2575 StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy);
2576 SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
2577
2578 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
2579 Constant *Initializer = MetadataInitializers[i];
2580 GlobalVariable *G = ExtendedGlobals[i];
2581 GlobalVariable *Metadata = CreateMetadataGlobal(Initializer, G->getName());
2582
2583 // On recent Mach-O platforms, we emit the global metadata in a way that
2584 // allows the linker to properly strip dead globals.
2585 auto LivenessBinder =
2586 ConstantStruct::get(LivenessTy, Initializer->getAggregateElement(0u),
2588 GlobalVariable *Liveness = new GlobalVariable(
2589 M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
2590 Twine("__asan_binder_") + G->getName());
2591 Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
2592 LivenessGlobals[i] = Liveness;
2593 }
2594
2595 // Update llvm.compiler.used, adding the new liveness globals. This is
2596 // needed so that during LTO these variables stay alive. The alternative
2597 // would be to have the linker handling the LTO symbols, but libLTO
2598 // current API does not expose access to the section for each symbol.
2599 if (!LivenessGlobals.empty())
2600 appendToCompilerUsed(M, LivenessGlobals);
2601
2602 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
2603 // to look up the loaded image that contains it. Second, we can store in it
2604 // whether registration has already occurred, to prevent duplicate
2605 // registration.
2606 //
2607 // common linkage ensures that there is only one global per shared library.
2608 GlobalVariable *RegisteredFlag = new GlobalVariable(
2609 M, IntptrTy, false, GlobalVariable::CommonLinkage,
2610 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
2612
2613 if (ConstructorKind == AsanCtorKind::Global)
2614 IRB.CreateCall(AsanRegisterImageGlobals,
2615 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
2616
2617 // We also need to unregister globals at the end, e.g., when a shared library
2618 // gets closed.
2619 if (DestructorKind != AsanDtorKind::None) {
2620 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2621 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2622 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
2623 }
2624}
2625
2626void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2627 IRBuilder<> &IRB, ArrayRef<GlobalVariable *> ExtendedGlobals,
2628 ArrayRef<Constant *> MetadataInitializers) {
2629 assert(ExtendedGlobals.size() == MetadataInitializers.size());
2630 unsigned N = ExtendedGlobals.size();
2631 assert(N > 0);
2632
2633 // On platforms that don't have a custom metadata section, we emit an array
2634 // of global metadata structures.
2635 ArrayType *ArrayOfGlobalStructTy =
2636 ArrayType::get(MetadataInitializers[0]->getType(), N);
2637 auto AllGlobals = new GlobalVariable(
2638 M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
2639 ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
2640 if (Mapping.Scale > 3)
2641 AllGlobals->setAlignment(Align(1ULL << Mapping.Scale));
2642
2643 if (ConstructorKind == AsanCtorKind::Global)
2644 IRB.CreateCall(AsanRegisterGlobals,
2645 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
2646 ConstantInt::get(IntptrTy, N)});
2647
2648 // We also need to unregister globals at the end, e.g., when a shared library
2649 // gets closed.
2650 if (DestructorKind != AsanDtorKind::None) {
2651 IRBuilder<> IrbDtor(CreateAsanModuleDtor());
2652 IrbDtor.CreateCall(AsanUnregisterGlobals,
2653 {IRB.CreatePointerCast(AllGlobals, IntptrTy),
2654 ConstantInt::get(IntptrTy, N)});
2655 }
2656}
2657
2658// This function replaces all global variables with new variables that have
2659// trailing redzones. It also creates a function that poisons
2660// redzones and inserts this function into llvm.global_ctors.
2661// Sets *CtorComdat to true if the global registration code emitted into the
2662// asan constructor is comdat-compatible.
2663void ModuleAddressSanitizer::instrumentGlobals(IRBuilder<> &IRB,
2664 bool *CtorComdat) {
2665 // Build set of globals that are aliased by some GA, where
2666 // getExcludedAliasedGlobal(GA) returns the relevant GlobalVariable.
2667 SmallPtrSet<const GlobalVariable *, 16> AliasedGlobalExclusions;
2668 if (CompileKernel) {
2669 for (auto &GA : M.aliases()) {
2670 if (const GlobalVariable *GV = getExcludedAliasedGlobal(GA))
2671 AliasedGlobalExclusions.insert(GV);
2672 }
2673 }
2674
2675 SmallVector<GlobalVariable *, 16> GlobalsToChange;
2676 for (auto &G : M.globals()) {
2677 if (!AliasedGlobalExclusions.count(&G) && shouldInstrumentGlobal(&G))
2678 GlobalsToChange.push_back(&G);
2679 }
2680
2681 size_t n = GlobalsToChange.size();
2682 auto &DL = M.getDataLayout();
2683
2684 // A global is described by a structure
2685 // size_t beg;
2686 // size_t size;
2687 // size_t size_with_redzone;
2688 // const char *name;
2689 // const char *module_name;
2690 // size_t has_dynamic_init;
2691 // size_t padding_for_windows_msvc_incremental_link;
2692 // size_t odr_indicator;
2693 // We initialize an array of such structures and pass it to a run-time call.
2694 StructType *GlobalStructTy =
2695 StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
2696 IntptrTy, IntptrTy, IntptrTy);
2698 SmallVector<Constant *, 16> Initializers(n);
2699
2700 for (size_t i = 0; i < n; i++) {
2701 GlobalVariable *G = GlobalsToChange[i];
2702
2704 if (G->hasSanitizerMetadata())
2705 MD = G->getSanitizerMetadata();
2706
2707 // The runtime library tries demangling symbol names in the descriptor but
2708 // functionality like __cxa_demangle may be unavailable (e.g.
2709 // -static-libstdc++). So we demangle the symbol names here.
2710 std::string NameForGlobal = G->getName().str();
2713 /*AllowMerging*/ true, genName("global"));
2714
2715 Type *Ty = G->getValueType();
2716 const uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
2717 const uint64_t RightRedzoneSize = getRedzoneSizeForGlobal(SizeInBytes);
2718 Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
2719
2720 StructType *NewTy = StructType::get(Ty, RightRedZoneTy);
2721 Constant *NewInitializer = ConstantStruct::get(
2722 NewTy, G->getInitializer(), Constant::getNullValue(RightRedZoneTy));
2723
2724 // Create a new global variable with enough space for a redzone.
2725 GlobalValue::LinkageTypes Linkage = G->getLinkage();
2726 if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage)
2728 GlobalVariable *NewGlobal = new GlobalVariable(
2729 M, NewTy, G->isConstant(), Linkage, NewInitializer, "", G,
2730 G->getThreadLocalMode(), G->getAddressSpace());
2731 NewGlobal->copyAttributesFrom(G);
2732 NewGlobal->setComdat(G->getComdat());
2733 NewGlobal->setAlignment(Align(getMinRedzoneSizeForGlobal()));
2734 // Don't fold globals with redzones. ODR violation detector and redzone
2735 // poisoning implicitly creates a dependence on the global's address, so it
2736 // is no longer valid for it to be marked unnamed_addr.
2738
2739 // Move null-terminated C strings to "__asan_cstring" section on Darwin.
2740 if (TargetTriple.isOSBinFormatMachO() && !G->hasSection() &&
2741 G->isConstant()) {
2742 auto Seq = dyn_cast<ConstantDataSequential>(G->getInitializer());
2743 if (Seq && Seq->isCString())
2744 NewGlobal->setSection("__TEXT,__asan_cstring,regular");
2745 }
2746
2747 // Transfer the debug info and type metadata. The payload starts at offset
2748 // zero so we can copy the metadata over as is.
2749 NewGlobal->copyMetadata(G, 0);
2750
2751 G->replaceAllUsesWith(NewGlobal);
2752 NewGlobal->takeName(G);
2753 G->eraseFromParent();
2754 NewGlobals[i] = NewGlobal;
2755
2756 Constant *ODRIndicator = Constant::getNullValue(IntptrTy);
2757 GlobalValue *InstrumentedGlobal = NewGlobal;
2758
2759 bool CanUsePrivateAliases =
2760 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2761 TargetTriple.isOSBinFormatWasm();
2762 if (CanUsePrivateAliases && UsePrivateAlias) {
2763 // Create local alias for NewGlobal to avoid crash on ODR between
2764 // instrumented and non-instrumented libraries.
2765 InstrumentedGlobal =
2767 }
2768
2769 // ODR should not happen for local linkage.
2770 if (NewGlobal->hasLocalLinkage()) {
2771 ODRIndicator = ConstantInt::getAllOnesValue(IntptrTy);
2772 } else if (UseOdrIndicator) {
2773 // With local aliases, we need to provide another externally visible
2774 // symbol __odr_asan_XXX to detect ODR violation.
2775 auto *ODRIndicatorSym =
2776 new GlobalVariable(M, IRB.getInt8Ty(), false, Linkage,
2778 kODRGenPrefix + NameForGlobal, nullptr,
2779 NewGlobal->getThreadLocalMode());
2780
2781 // Set meaningful attributes for indicator symbol.
2782 ODRIndicatorSym->setVisibility(NewGlobal->getVisibility());
2783 ODRIndicatorSym->setDLLStorageClass(NewGlobal->getDLLStorageClass());
2784 ODRIndicatorSym->setAlignment(Align(1));
2785 ODRIndicator = ConstantExpr::getPtrToInt(ODRIndicatorSym, IntptrTy);
2786 }
2787
2788 Constant *Initializer = ConstantStruct::get(
2789 GlobalStructTy,
2790 ConstantExpr::getPointerCast(InstrumentedGlobal, IntptrTy),
2791 ConstantInt::get(IntptrTy, SizeInBytes),
2792 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2793 ConstantExpr::getPointerCast(Name, IntptrTy),
2794 ConstantExpr::getPointerCast(getOrCreateModuleName(), IntptrTy),
2795 ConstantInt::get(IntptrTy, MD.IsDynInit),
2796 Constant::getNullValue(IntptrTy), ODRIndicator);
2797
2798 LLVM_DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
2799
2800 Initializers[i] = Initializer;
2801 }
2802
2803 // Add instrumented globals to llvm.compiler.used list to avoid LTO from
2804 // ConstantMerge'ing them.
2805 SmallVector<GlobalValue *, 16> GlobalsToAddToUsedList;
2806 for (size_t i = 0; i < n; i++) {
2807 GlobalVariable *G = NewGlobals[i];
2808 if (G->getName().empty()) continue;
2809 GlobalsToAddToUsedList.push_back(G);
2810 }
2811 appendToCompilerUsed(M, ArrayRef<GlobalValue *>(GlobalsToAddToUsedList));
2812
2813 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2814 // Use COMDAT and register globals even if n == 0 to ensure that (a) the
2815 // linkage unit will only have one module constructor, and (b) the register
2816 // function will be called. The module destructor is not created when n ==
2817 // 0.
2818 *CtorComdat = true;
2819 instrumentGlobalsELF(IRB, NewGlobals, Initializers, getUniqueModuleId(&M));
2820 } else if (n == 0) {
2821 // When UseGlobalsGC is false, COMDAT can still be used if n == 0, because
2822 // all compile units will have identical module constructor/destructor.
2823 *CtorComdat = TargetTriple.isOSBinFormatELF();
2824 } else {
2825 *CtorComdat = false;
2826 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2827 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2828 } else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2829 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2830 } else {
2831 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2832 }
2833 }
2834
2835 // Create calls for poisoning before initializers run and unpoisoning after.
2836 if (ClInitializers)
2837 createInitializerPoisonCalls();
2838
2839 LLVM_DEBUG(dbgs() << M);
2840}
2841
2843ModuleAddressSanitizer::getRedzoneSizeForGlobal(uint64_t SizeInBytes) const {
2844 constexpr uint64_t kMaxRZ = 1 << 18;
2845 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2846
2847 uint64_t RZ = 0;
2848 if (SizeInBytes <= MinRZ / 2) {
2849 // Reduce redzone size for small size objects, e.g. int, char[1]. MinRZ is
2850 // at least 32 bytes, optimize when SizeInBytes is less than or equal to
2851 // half of MinRZ.
2852 RZ = MinRZ - SizeInBytes;
2853 } else {
2854 // Calculate RZ, where MinRZ <= RZ <= MaxRZ, and RZ ~ 1/4 * SizeInBytes.
2855 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2856
2857 // Round up to multiple of MinRZ.
2858 if (SizeInBytes % MinRZ)
2859 RZ += MinRZ - (SizeInBytes % MinRZ);
2860 }
2861
2862 assert((RZ + SizeInBytes) % MinRZ == 0);
2863
2864 return RZ;
2865}
2866
2867int ModuleAddressSanitizer::GetAsanVersion() const {
2868 int LongSize = M.getDataLayout().getPointerSizeInBits();
2869 bool isAndroid = M.getTargetTriple().isAndroid();
2870 int Version = 8;
2871 // 32-bit Android is one version ahead because of the switch to dynamic
2872 // shadow.
2873 Version += (LongSize == 32 && isAndroid);
2874 return Version;
2875}
2876
2877GlobalVariable *ModuleAddressSanitizer::getOrCreateModuleName() {
2878 if (!ModuleName) {
2879 // We shouldn't merge same module names, as this string serves as unique
2880 // module ID in runtime.
2881 ModuleName =
2882 createPrivateGlobalForString(M, M.getModuleIdentifier(),
2883 /*AllowMerging*/ false, genName("module"));
2884 }
2885 return ModuleName;
2886}
2887
2888bool ModuleAddressSanitizer::instrumentModule() {
2889 initializeCallbacks();
2890
2891 for (Function &F : M)
2892 removeASanIncompatibleFnAttributes(F, /*ReadsArgMem=*/false);
2893
2894 // Create a module constructor. A destructor is created lazily because not all
2895 // platforms, and not all modules need it.
2896 if (ConstructorKind == AsanCtorKind::Global) {
2897 if (CompileKernel) {
2898 // The kernel always builds with its own runtime, and therefore does not
2899 // need the init and version check calls.
2900 AsanCtorFunction = createSanitizerCtor(M, kAsanModuleCtorName);
2901 } else {
2902 std::string AsanVersion = std::to_string(GetAsanVersion());
2903 std::string VersionCheckName =
2904 InsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : "";
2905 std::tie(AsanCtorFunction, std::ignore) =
2907 M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{},
2908 /*InitArgs=*/{}, VersionCheckName);
2909 }
2910 }
2911
2912 bool CtorComdat = true;
2913 if (ClGlobals) {
2914 assert(AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
2915 if (AsanCtorFunction) {
2916 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2917 instrumentGlobals(IRB, &CtorComdat);
2918 } else {
2919 IRBuilder<> IRB(*C);
2920 instrumentGlobals(IRB, &CtorComdat);
2921 }
2922 }
2923
2924 const uint64_t Priority = GetCtorAndDtorPriority(TargetTriple);
2925
2926 // Put the constructor and destructor in comdat if both
2927 // (1) global instrumentation is not TU-specific
2928 // (2) target is ELF.
2929 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2930 if (AsanCtorFunction) {
2931 AsanCtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleCtorName));
2932 appendToGlobalCtors(M, AsanCtorFunction, Priority, AsanCtorFunction);
2933 }
2934 if (AsanDtorFunction) {
2935 AsanDtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleDtorName));
2936 appendToGlobalDtors(M, AsanDtorFunction, Priority, AsanDtorFunction);
2937 }
2938 } else {
2939 if (AsanCtorFunction)
2940 appendToGlobalCtors(M, AsanCtorFunction, Priority);
2941 if (AsanDtorFunction)
2942 appendToGlobalDtors(M, AsanDtorFunction, Priority);
2943 }
2944
2945 return true;
2946}
2947
2948void AddressSanitizer::initializeCallbacks(const TargetLibraryInfo *TLI) {
2949 IRBuilder<> IRB(*C);
2950 // Create __asan_report* callbacks.
2951 // IsWrite, TypeSize and Exp are encoded in the function name.
2952 for (int Exp = 0; Exp < 2; Exp++) {
2953 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2954 const std::string TypeStr = AccessIsWrite ? "store" : "load";
2955 const std::string ExpStr = Exp ? "exp_" : "";
2956 const std::string EndingStr = Recover ? "_noabort" : "";
2957
2958 SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
2959 SmallVector<Type *, 2> Args1{1, IntptrTy};
2960 AttributeList AL2;
2961 AttributeList AL1;
2962 if (Exp) {
2963 Type *ExpType = Type::getInt32Ty(*C);
2964 Args2.push_back(ExpType);
2965 Args1.push_back(ExpType);
2966 if (auto AK = TLI->getExtAttrForI32Param(false)) {
2967 AL2 = AL2.addParamAttribute(*C, 2, AK);
2968 AL1 = AL1.addParamAttribute(*C, 1, AK);
2969 }
2970 }
2971 AsanErrorCallbackSized[AccessIsWrite][Exp] = Inserter.insertFunction(
2972 kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr,
2973 FunctionType::get(IRB.getVoidTy(), Args2, false), AL2);
2974
2975 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
2976 Inserter.insertFunction(
2977 ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr,
2978 FunctionType::get(IRB.getVoidTy(), Args2, false), AL2);
2979
2980 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
2981 AccessSizeIndex++) {
2982 const std::string Suffix = TypeStr + itostr(1ULL << AccessSizeIndex);
2983 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2984 Inserter.insertFunction(
2985 kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr,
2986 FunctionType::get(IRB.getVoidTy(), Args1, false), AL1);
2987
2988 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2989 Inserter.insertFunction(
2990 ClMemoryAccessCallbackPrefix + ExpStr + Suffix + EndingStr,
2991 FunctionType::get(IRB.getVoidTy(), Args1, false), AL1);
2992 }
2993 }
2994 }
2995
2996 const std::string MemIntrinCallbackPrefix =
2997 (CompileKernel && !ClKasanMemIntrinCallbackPrefix)
2998 ? std::string("")
3000 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix + "memmove",
3001 PtrTy, PtrTy, PtrTy, IntptrTy);
3002 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix + "memcpy",
3003 PtrTy, PtrTy, PtrTy, IntptrTy);
3004 AsanMemset =
3005 Inserter.insertFunction(MemIntrinCallbackPrefix + "memset",
3006 TLI->getAttrList(C, {1},
3007 /*Signed=*/false),
3008 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
3009
3010 AsanHandleNoReturnFunc =
3011 Inserter.insertFunction(kAsanHandleNoReturnName, IRB.getVoidTy());
3012
3013 AsanPtrCmpFunction =
3014 Inserter.insertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy);
3015 AsanPtrSubFunction =
3016 Inserter.insertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy);
3017 if (Mapping.InGlobal)
3018 AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow",
3019 ArrayType::get(IRB.getInt8Ty(), 0));
3020
3021 AMDGPUAddressShared =
3022 Inserter.insertFunction(kAMDGPUAddressSharedName, IRB.getInt1Ty(), PtrTy);
3023 AMDGPUAddressPrivate = Inserter.insertFunction(kAMDGPUAddressPrivateName,
3024 IRB.getInt1Ty(), PtrTy);
3025}
3026
3027bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
3028 // For each NSObject descendant having a +load method, this method is invoked
3029 // by the ObjC runtime before any of the static constructors is called.
3030 // Therefore we need to instrument such methods with a call to __asan_init
3031 // at the beginning in order to initialize our runtime before any access to
3032 // the shadow memory.
3033 // We cannot just ignore these methods, because they may call other
3034 // instrumented functions.
3035 if (F.getName().contains(" load]")) {
3036 FunctionCallee AsanInitFunction =
3037 declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {});
3038 IRBuilder<> IRB(&F.front(), F.front().begin());
3039 IRB.CreateCall(AsanInitFunction, {});
3040 return true;
3041 }
3042 return false;
3043}
3044
3045bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(Function &F) {
3046 // Generate code only when dynamic addressing is needed.
3047 if (Mapping.Offset != kDynamicShadowSentinel)
3048 return false;
3049
3050 IRBuilder<> IRB(&F.front().front());
3051 if (Mapping.InGlobal) {
3053 // An empty inline asm with input reg == output reg.
3054 // An opaque pointer-to-int cast, basically.
3056 FunctionType::get(IntptrTy, {AsanShadowGlobal->getType()}, false),
3057 StringRef(""), StringRef("=r,0"),
3058 /*hasSideEffects=*/false);
3059 LocalDynamicShadow =
3060 IRB.CreateCall(Asm, {AsanShadowGlobal}, ".asan.shadow");
3061 } else {
3062 LocalDynamicShadow =
3063 IRB.CreatePointerCast(AsanShadowGlobal, IntptrTy, ".asan.shadow");
3064 }
3065 } else {
3066 Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
3068 LocalDynamicShadow = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
3069 }
3070 return true;
3071}
3072
3073void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
3074 // Find the one possible call to llvm.localescape and pre-mark allocas passed
3075 // to it as uninteresting. This assumes we haven't started processing allocas
3076 // yet. This check is done up front because iterating the use list in
3077 // isInterestingAlloca would be algorithmically slower.
3078 assert(ProcessedAllocas.empty() && "must process localescape before allocas");
3079
3080 // Try to get the declaration of llvm.localescape. If it's not in the module,
3081 // we can exit early.
3082 if (!F.getParent()->getFunction("llvm.localescape")) return;
3083
3084 // Look for a call to llvm.localescape call in the entry block. It can't be in
3085 // any other block.
3086 for (Instruction &I : F.getEntryBlock()) {
3088 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
3089 // We found a call. Mark all the allocas passed in as uninteresting.
3090 for (Value *Arg : II->args()) {
3091 AllocaInst *AI = dyn_cast<AllocaInst>(Arg->stripPointerCasts());
3092 assert(AI && AI->isStaticAlloca() &&
3093 "non-static alloca arg to localescape");
3094 ProcessedAllocas[AI] = false;
3095 }
3096 break;
3097 }
3098 }
3099}
3100// Mitigation for https://github.com/google/sanitizers/issues/749
3101// We don't instrument Windows catch-block parameters to avoid
3102// interfering with exception handling assumptions.
3103void AddressSanitizer::markCatchParametersAsUninteresting(Function &F) {
3104 for (BasicBlock &BB : F) {
3105 for (Instruction &I : BB) {
3106 if (auto *CatchPad = dyn_cast<CatchPadInst>(&I)) {
3107 // Mark the parameters to a catch-block as uninteresting to avoid
3108 // instrumenting them.
3109 for (Value *Operand : CatchPad->arg_operands())
3110 if (auto *AI = dyn_cast<AllocaInst>(Operand))
3111 ProcessedAllocas[AI] = false;
3112 }
3113 }
3114 }
3115}
3116
3117bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) {
3118 bool ShouldInstrument =
3119 ClDebugMin < 0 || ClDebugMax < 0 ||
3120 (Instrumented >= ClDebugMin && Instrumented <= ClDebugMax);
3121 Instrumented++;
3122 return !ShouldInstrument;
3123}
3124
3125bool AddressSanitizer::instrumentFunction(Function &F,
3126 const TargetLibraryInfo *TLI,
3127 const TargetTransformInfo *TTI) {
3128 bool FunctionModified = false;
3129
3130 // Do not apply any instrumentation for naked functions.
3131 if (F.hasFnAttribute(Attribute::Naked))
3132 return FunctionModified;
3133
3134 // If needed, insert __asan_init before checking for SanitizeAddress attr.
3135 // This function needs to be called even if the function body is not
3136 // instrumented.
3137 if (maybeInsertAsanInitAtFunctionEntry(F))
3138 FunctionModified = true;
3139
3140 // Leave if the function doesn't need instrumentation.
3141 if (!F.hasFnAttribute(Attribute::SanitizeAddress)) return FunctionModified;
3142
3143 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3144 return FunctionModified;
3145
3146 LLVM_DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
3147
3148 initializeCallbacks(TLI);
3149
3150 FunctionStateRAII CleanupObj(this);
3151
3152 RuntimeCallInserter RTCI(F);
3153
3154 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(F);
3155
3156 // We can't instrument allocas used with llvm.localescape. Only static allocas
3157 // can be passed to that intrinsic.
3158 markEscapedLocalAllocas(F);
3159
3160 if (TargetTriple.isOSWindows())
3161 markCatchParametersAsUninteresting(F);
3162
3163 // We want to instrument every address only once per basic block (unless there
3164 // are calls between uses).
3165 SmallPtrSet<Value *, 16> TempsToInstrument;
3166 SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
3167 SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
3168 SmallVector<Instruction *, 8> NoReturnCalls;
3170 SmallVector<Instruction *, 16> PointerComparisonsOrSubtracts;
3171
3172 // Fill the set of memory operations to instrument.
3173 for (auto &BB : F) {
3174 AllBlocks.push_back(&BB);
3175 TempsToInstrument.clear();
3176 int NumInsnsPerBB = 0;
3177 for (auto &Inst : BB) {
3178 if (LooksLikeCodeInBug11395(&Inst)) return false;
3179 // Skip instructions inserted by another instrumentation.
3180 if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
3181 continue;
3182 SmallVector<InterestingMemoryOperand, 1> InterestingOperands;
3183 getInterestingMemoryOperands(&Inst, InterestingOperands, TTI);
3184
3185 if (!InterestingOperands.empty()) {
3186 for (auto &Operand : InterestingOperands) {
3187 if (ClOpt && ClOptSameTemp) {
3188 Value *Ptr = Operand.getPtr();
3189 // If we have a mask, skip instrumentation if we've already
3190 // instrumented the full object. But don't add to TempsToInstrument
3191 // because we might get another load/store with a different mask.
3192 if (Operand.MaybeMask) {
3193 if (TempsToInstrument.count(Ptr))
3194 continue; // We've seen this (whole) temp in the current BB.
3195 } else {
3196 if (!TempsToInstrument.insert(Ptr).second)
3197 continue; // We've seen this temp in the current BB.
3198 }
3199 }
3200 OperandsToInstrument.push_back(Operand);
3201 NumInsnsPerBB++;
3202 }
3203 } else if (((ClInvalidPointerPairs || ClInvalidPointerCmp) &&
3207 PointerComparisonsOrSubtracts.push_back(&Inst);
3208 } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst)) {
3209 // ok, take it.
3210 IntrinToInstrument.push_back(MI);
3211 NumInsnsPerBB++;
3212 } else {
3213 if (auto *CB = dyn_cast<CallBase>(&Inst)) {
3214 // A call inside BB.
3215 TempsToInstrument.clear();
3216 if (CB->doesNotReturn())
3217 NoReturnCalls.push_back(CB);
3218 }
3219 if (CallInst *CI = dyn_cast<CallInst>(&Inst))
3221 }
3222 if (NumInsnsPerBB >= ClMaxInsnsToInstrumentPerBB) break;
3223 }
3224 }
3225
3226 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3227 OperandsToInstrument.size() + IntrinToInstrument.size() >
3228 (unsigned)InstrumentationWithCallsThreshold);
3229 const DataLayout &DL = F.getDataLayout();
3230 ObjectSizeOffsetVisitor ObjSizeVis(DL, TLI, F.getContext());
3231
3232 // Instrument.
3233 int NumInstrumented = 0;
3234 for (auto &Operand : OperandsToInstrument) {
3235 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3236 instrumentMop(ObjSizeVis, Operand, UseCalls,
3237 F.getDataLayout(), RTCI);
3238 FunctionModified = true;
3239 }
3240 for (auto *Inst : IntrinToInstrument) {
3241 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3242 instrumentMemIntrinsic(Inst, RTCI);
3243 FunctionModified = true;
3244 }
3245
3246 FunctionStackPoisoner FSP(F, *this, RTCI);
3247 bool ChangedStack = FSP.runOnFunction();
3248
3249 // We must unpoison the stack before NoReturn calls (throw, _exit, etc).
3250 // See e.g. https://github.com/google/sanitizers/issues/37
3251 for (auto *CI : NoReturnCalls) {
3252 IRBuilder<> IRB(CI);
3253 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3254 }
3255
3256 for (auto *Inst : PointerComparisonsOrSubtracts) {
3257 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3258 }
3259
3260 if (ChangedStack || !NoReturnCalls.empty())
3261 FunctionModified = true;
3262
3263 LLVM_DEBUG(dbgs() << "ASAN done instrumenting: " << FunctionModified << " "
3264 << F << "\n");
3265
3266 return FunctionModified;
3267}
3268
3269// Workaround for bug 11395: we don't want to instrument stack in functions
3270// with large assembly blobs (32-bit only), otherwise reg alloc may crash.
3271// FIXME: remove once the bug 11395 is fixed.
3272bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) {
3273 if (LongSize != 32) return false;
3275 if (!CI || !CI->isInlineAsm()) return false;
3276 if (CI->arg_size() <= 5)
3277 return false;
3278 // We have inline assembly with quite a few arguments.
3279 return true;
3280}
3281
3282void FunctionStackPoisoner::initializeCallbacks(Module &) {
3283 IRBuilder<> IRB(*C);
3284 if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always ||
3285 ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
3286 const char *MallocNameTemplate =
3287 ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always
3290 for (int Index = 0; Index <= kMaxAsanStackMallocSizeClass; Index++) {
3291 std::string Suffix = itostr(Index);
3292 AsanStackMallocFunc[Index] = ASan.Inserter.insertFunction(
3293 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3294 AsanStackFreeFunc[Index] =
3295 ASan.Inserter.insertFunction(kAsanStackFreeNameTemplate + Suffix,
3296 IRB.getVoidTy(), IntptrTy, IntptrTy);
3297 }
3298 }
3299 if (ASan.UseAfterScope) {
3300 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3301 kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
3302 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3303 kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
3304 }
3305
3306 for (size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3307 0xf3, 0xf5, 0xf8}) {
3308 std::ostringstream Name;
3310 Name << std::setw(2) << std::setfill('0') << std::hex << Val;
3311 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3312 Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy);
3313 }
3314
3315 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3316 kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
3317 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3318 kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy);
3319}
3320
3321void FunctionStackPoisoner::copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
3322 ArrayRef<uint8_t> ShadowBytes,
3323 size_t Begin, size_t End,
3324 IRBuilder<> &IRB,
3325 Value *ShadowBase) {
3326 if (Begin >= End)
3327 return;
3328
3329 const size_t LargestStoreSizeInBytes =
3330 std::min<size_t>(sizeof(uint64_t), ASan.LongSize / 8);
3331
3332 const bool IsLittleEndian = F.getDataLayout().isLittleEndian();
3333
3334 // Poison given range in shadow using larges store size with out leading and
3335 // trailing zeros in ShadowMask. Zeros never change, so they need neither
3336 // poisoning nor up-poisoning. Still we don't mind if some of them get into a
3337 // middle of a store.
3338 for (size_t i = Begin; i < End;) {
3339 if (!ShadowMask[i]) {
3340 assert(!ShadowBytes[i]);
3341 ++i;
3342 continue;
3343 }
3344
3345 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3346 // Fit store size into the range.
3347 while (StoreSizeInBytes > End - i)
3348 StoreSizeInBytes /= 2;
3349
3350 // Minimize store size by trimming trailing zeros.
3351 for (size_t j = StoreSizeInBytes - 1; j && !ShadowMask[i + j]; --j) {
3352 while (j <= StoreSizeInBytes / 2)
3353 StoreSizeInBytes /= 2;
3354 }
3355
3356 uint64_t Val = 0;
3357 for (size_t j = 0; j < StoreSizeInBytes; j++) {
3358 if (IsLittleEndian)
3359 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
3360 else
3361 Val = (Val << 8) | ShadowBytes[i + j];
3362 }
3363
3364 Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3365 Value *Poison = IRB.getIntN(StoreSizeInBytes * 8, Val);
3367 Poison, IRB.CreateIntToPtr(Ptr, PointerType::getUnqual(Poison->getContext())),
3368 Align(1));
3369
3370 i += StoreSizeInBytes;
3371 }
3372}
3373
3374void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
3375 ArrayRef<uint8_t> ShadowBytes,
3376 IRBuilder<> &IRB, Value *ShadowBase) {
3377 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.size(), IRB, ShadowBase);
3378}
3379
3380void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
3381 ArrayRef<uint8_t> ShadowBytes,
3382 size_t Begin, size_t End,
3383 IRBuilder<> &IRB, Value *ShadowBase) {
3384 assert(ShadowMask.size() == ShadowBytes.size());
3385 size_t Done = Begin;
3386 for (size_t i = Begin, j = Begin + 1; i < End; i = j++) {
3387 if (!ShadowMask[i]) {
3388 assert(!ShadowBytes[i]);
3389 continue;
3390 }
3391 uint8_t Val = ShadowBytes[i];
3392 if (!AsanSetShadowFunc[Val])
3393 continue;
3394
3395 // Skip same values.
3396 for (; j < End && ShadowMask[j] && Val == ShadowBytes[j]; ++j) {
3397 }
3398
3399 if (j - i >= ASan.MaxInlinePoisoningSize) {
3400 copyToShadowInline(ShadowMask, ShadowBytes, Done, i, IRB, ShadowBase);
3401 RTCI.createRuntimeCall(
3402 IRB, AsanSetShadowFunc[Val],
3403 {IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3404 ConstantInt::get(IntptrTy, j - i)});
3405 Done = j;
3406 }
3407 }
3408
3409 copyToShadowInline(ShadowMask, ShadowBytes, Done, End, IRB, ShadowBase);
3410}
3411
3412// Fake stack allocator (asan_fake_stack.h) has 11 size classes
3413// for every power of 2 from kMinStackMallocSize to kMaxAsanStackMallocSizeClass
3414static int StackMallocSizeClass(uint64_t LocalStackSize) {
3415 assert(LocalStackSize <= kMaxStackMallocSize);
3416 uint64_t MaxSize = kMinStackMallocSize;
3417 for (int i = 0;; i++, MaxSize *= 2)
3418 if (LocalStackSize <= MaxSize) return i;
3419 llvm_unreachable("impossible LocalStackSize");
3420}
3421
3422void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3423 Instruction *CopyInsertPoint = &F.front().front();
3424 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3425 // Insert after the dynamic shadow location is determined
3426 CopyInsertPoint = CopyInsertPoint->getNextNode();
3427 assert(CopyInsertPoint);
3428 }
3429 IRBuilder<> IRB(CopyInsertPoint);
3430 const DataLayout &DL = F.getDataLayout();
3431 for (Argument &Arg : F.args()) {
3432 if (Arg.hasByValAttr()) {
3433 Type *Ty = Arg.getParamByValType();
3434 const Align Alignment =
3435 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3436
3437 AllocaInst *AI = IRB.CreateAlloca(
3438 Ty, nullptr,
3439 (Arg.hasName() ? Arg.getName() : "Arg" + Twine(Arg.getArgNo())) +
3440 ".byval");
3441 AI->setAlignment(Alignment);
3442 Arg.replaceAllUsesWith(AI);
3443
3444 uint64_t AllocSize = DL.getTypeAllocSize(Ty);
3445 IRB.CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3446 }
3447 }
3448}
3449
3450PHINode *FunctionStackPoisoner::createPHI(IRBuilder<> &IRB, Value *Cond,
3451 Value *ValueIfTrue,
3452 Instruction *ThenTerm,
3453 Value *ValueIfFalse) {
3454 PHINode *PHI = IRB.CreatePHI(ValueIfTrue->getType(), 2);
3455 BasicBlock *CondBlock = cast<Instruction>(Cond)->getParent();
3456 PHI->addIncoming(ValueIfFalse, CondBlock);
3457 BasicBlock *ThenBlock = ThenTerm->getParent();
3458 PHI->addIncoming(ValueIfTrue, ThenBlock);
3459 return PHI;
3460}
3461
3462Value *FunctionStackPoisoner::createAllocaForLayout(
3463 IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) {
3464 AllocaInst *Alloca;
3465 if (Dynamic) {
3466 Alloca = IRB.CreateAlloca(IRB.getInt8Ty(),
3467 ConstantInt::get(IRB.getInt64Ty(), L.FrameSize),
3468 "MyAlloca");
3469 } else {
3470 Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize),
3471 nullptr, "MyAlloca");
3472 assert(Alloca->isStaticAlloca());
3473 }
3474 assert((ClRealignStack & (ClRealignStack - 1)) == 0);
3475 uint64_t FrameAlignment = std::max(L.FrameAlignment, uint64_t(ClRealignStack));
3476 Alloca->setAlignment(Align(FrameAlignment));
3477 return Alloca;
3478}
3479
3480void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3481 BasicBlock &FirstBB = *F.begin();
3482 IRBuilder<> IRB(dyn_cast<Instruction>(FirstBB.begin()));
3483 DynamicAllocaLayout = IRB.CreateAlloca(IntptrTy, nullptr);
3484 IRB.CreateStore(Constant::getNullValue(IntptrTy), DynamicAllocaLayout);
3485 DynamicAllocaLayout->setAlignment(Align(32));
3486}
3487
3488void FunctionStackPoisoner::processDynamicAllocas() {
3489 if (!ClInstrumentDynamicAllocas || DynamicAllocaVec.empty()) {
3490 assert(DynamicAllocaPoisonCallVec.empty());
3491 return;
3492 }
3493
3494 // Insert poison calls for lifetime intrinsics for dynamic allocas.
3495 for (const auto &APC : DynamicAllocaPoisonCallVec) {
3496 assert(APC.InsBefore);
3497 assert(APC.AI);
3498 assert(ASan.isInterestingAlloca(*APC.AI));
3499 assert(!APC.AI->isStaticAlloca());
3500
3501 IRBuilder<> IRB(APC.InsBefore);
3502 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3503 // Dynamic allocas will be unpoisoned unconditionally below in
3504 // unpoisonDynamicAllocas.
3505 // Flag that we need unpoison static allocas.
3506 }
3507
3508 // Handle dynamic allocas.
3509 createDynamicAllocasInitStorage();
3510 for (auto &AI : DynamicAllocaVec)
3511 handleDynamicAllocaCall(AI);
3512 unpoisonDynamicAllocas();
3513}
3514
3515/// Collect instructions in the entry block after \p InsBefore which initialize
3516/// permanent storage for a function argument. These instructions must remain in
3517/// the entry block so that uninitialized values do not appear in backtraces. An
3518/// added benefit is that this conserves spill slots. This does not move stores
3519/// before instrumented / "interesting" allocas.
3521 AddressSanitizer &ASan, Instruction &InsBefore,
3522 SmallVectorImpl<Instruction *> &InitInsts) {
3523 Instruction *Start = InsBefore.getNextNode();
3524 for (Instruction *It = Start; It; It = It->getNextNode()) {
3525 // Argument initialization looks like:
3526 // 1) store <Argument>, <Alloca> OR
3527 // 2) <CastArgument> = cast <Argument> to ...
3528 // store <CastArgument> to <Alloca>
3529 // Do not consider any other kind of instruction.
3530 //
3531 // Note: This covers all known cases, but may not be exhaustive. An
3532 // alternative to pattern-matching stores is to DFS over all Argument uses:
3533 // this might be more general, but is probably much more complicated.
3534 if (isa<AllocaInst>(It) || isa<CastInst>(It))
3535 continue;
3536 if (auto *Store = dyn_cast<StoreInst>(It)) {
3537 // The store destination must be an alloca that isn't interesting for
3538 // ASan to instrument. These are moved up before InsBefore, and they're
3539 // not interesting because allocas for arguments can be mem2reg'd.
3540 auto *Alloca = dyn_cast<AllocaInst>(Store->getPointerOperand());
3541 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3542 continue;
3543
3544 Value *Val = Store->getValueOperand();
3545 bool IsDirectArgInit = isa<Argument>(Val);
3546 bool IsArgInitViaCast =
3547 isa<CastInst>(Val) &&
3548 isa<Argument>(cast<CastInst>(Val)->getOperand(0)) &&
3549 // Check that the cast appears directly before the store. Otherwise
3550 // moving the cast before InsBefore may break the IR.
3551 Val == It->getPrevNode();
3552 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3553 if (!IsArgInit)
3554 continue;
3555
3556 if (IsArgInitViaCast)
3557 InitInsts.push_back(cast<Instruction>(Val));
3558 InitInsts.push_back(Store);
3559 continue;
3560 }
3561
3562 // Do not reorder past unknown instructions: argument initialization should
3563 // only involve casts and stores.
3564 return;
3565 }
3566}
3567
3569 // Alloca could have been renamed for uniqueness. Its true name will have been
3570 // recorded as an annotation.
3571 if (AI->hasMetadata(LLVMContext::MD_annotation)) {
3572 MDTuple *AllocaAnnotations =
3573 cast<MDTuple>(AI->getMetadata(LLVMContext::MD_annotation));
3574 for (auto &Annotation : AllocaAnnotations->operands()) {
3575 if (!isa<MDTuple>(Annotation))
3576 continue;
3577 auto AnnotationTuple = cast<MDTuple>(Annotation);
3578 for (unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3579 Index++) {
3580 // All annotations are strings
3581 auto MetadataString =
3582 cast<MDString>(AnnotationTuple->getOperand(Index));
3583 if (MetadataString->getString() == "alloca_name_altered")
3584 return cast<MDString>(AnnotationTuple->getOperand(Index + 1))
3585 ->getString();
3586 }
3587 }
3588 }
3589 return AI->getName();
3590}
3591
3592void FunctionStackPoisoner::processStaticAllocas() {
3593 if (AllocaVec.empty()) {
3594 assert(StaticAllocaPoisonCallVec.empty());
3595 return;
3596 }
3597
3598 int StackMallocIdx = -1;
3599 DebugLoc EntryDebugLocation;
3600 if (auto SP = F.getSubprogram())
3601 EntryDebugLocation =
3602 DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
3603
3604 Instruction *InsBefore = AllocaVec[0];
3605 IRBuilder<> IRB(InsBefore);
3606
3607 // Make sure non-instrumented allocas stay in the entry block. Otherwise,
3608 // debug info is broken, because only entry-block allocas are treated as
3609 // regular stack slots.
3610 auto InsBeforeB = InsBefore->getParent();
3611 assert(InsBeforeB == &F.getEntryBlock());
3612 for (auto *AI : StaticAllocasToMoveUp)
3613 if (AI->getParent() == InsBeforeB)
3614 AI->moveBefore(InsBefore->getIterator());
3615
3616 // Move stores of arguments into entry-block allocas as well. This prevents
3617 // extra stack slots from being generated (to house the argument values until
3618 // they can be stored into the allocas). This also prevents uninitialized
3619 // values from being shown in backtraces.
3620 SmallVector<Instruction *, 8> ArgInitInsts;
3621 findStoresToUninstrumentedArgAllocas(ASan, *InsBefore, ArgInitInsts);
3622 for (Instruction *ArgInitInst : ArgInitInsts)
3623 ArgInitInst->moveBefore(InsBefore->getIterator());
3624
3625 // If we have a call to llvm.localescape, keep it in the entry block.
3626 if (LocalEscapeCall)
3627 LocalEscapeCall->moveBefore(InsBefore->getIterator());
3628
3630 SVD.reserve(AllocaVec.size());
3631 for (AllocaInst *AI : AllocaVec) {
3634 ASan.getAllocaSizeInBytes(*AI),
3635 0,
3636 AI->getAlign().value(),
3637 AI,
3638 0,
3639 0};
3640 SVD.push_back(D);
3641 }
3642
3643 // Minimal header size (left redzone) is 4 pointers,
3644 // i.e. 32 bytes on 64-bit platforms and 16 bytes in 32-bit platforms.
3645 uint64_t Granularity = 1ULL << Mapping.Scale;
3646 uint64_t MinHeaderSize = std::max((uint64_t)ASan.LongSize / 2, Granularity);
3647 const ASanStackFrameLayout &L =
3648 ComputeASanStackFrameLayout(SVD, Granularity, MinHeaderSize);
3649
3650 // Build AllocaToSVDMap for ASanStackVariableDescription lookup.
3652 for (auto &Desc : SVD)
3653 AllocaToSVDMap[Desc.AI] = &Desc;
3654
3655 // Update SVD with information from lifetime intrinsics.
3656 for (const auto &APC : StaticAllocaPoisonCallVec) {
3657 assert(APC.InsBefore);
3658 assert(APC.AI);
3659 assert(ASan.isInterestingAlloca(*APC.AI));
3660 assert(APC.AI->isStaticAlloca());
3661
3662 ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI];
3663 Desc.LifetimeSize = Desc.Size;
3664 if (const DILocation *FnLoc = EntryDebugLocation.get()) {
3665 if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3666 if (LifetimeLoc->getFile() == FnLoc->getFile())
3667 if (unsigned Line = LifetimeLoc->getLine())
3668 Desc.Line = std::min(Desc.Line ? Desc.Line : Line, Line);
3669 }
3670 }
3671 }
3672
3673 auto DescriptionString = ComputeASanStackFrameDescription(SVD);
3674 LLVM_DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n");
3675 uint64_t LocalStackSize = L.FrameSize;
3676 bool DoStackMalloc =
3677 ASan.UseAfterReturn != AsanDetectStackUseAfterReturnMode::Never &&
3678 !ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize;
3679 bool DoDynamicAlloca = ClDynamicAllocaStack;
3680 // Don't do dynamic alloca or stack malloc if:
3681 // 1) There is inline asm: too often it makes assumptions on which registers
3682 // are available.
3683 // 2) There is a returns_twice call (typically setjmp), which is
3684 // optimization-hostile, and doesn't play well with introduced indirect
3685 // register-relative calculation of local variable addresses.
3686 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3687 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3688
3689 Type *PtrTy = F.getDataLayout().getAllocaPtrType(F.getContext());
3690 Value *StaticAlloca =
3691 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false);
3692
3693 Value *FakeStackPtr;
3694 Value *FakeStackInt;
3695 Value *LocalStackBase;
3696 Value *LocalStackBaseAlloca;
3697 uint8_t DIExprFlags = DIExpression::ApplyOffset;
3698
3699 if (DoStackMalloc) {
3700 LocalStackBaseAlloca =
3701 IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base");
3702 if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
3703 // void *FakeStack = __asan_option_detect_stack_use_after_return
3704 // ? __asan_stack_malloc_N(LocalStackSize)
3705 // : nullptr;
3706 // void *LocalStackBase = (FakeStack) ? FakeStack :
3707 // alloca(LocalStackSize);
3708 Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal(
3710 Value *UseAfterReturnIsEnabled = IRB.CreateICmpNE(
3711 IRB.CreateLoad(IRB.getInt32Ty(), OptionDetectUseAfterReturn),
3713 Instruction *Term =
3714 SplitBlockAndInsertIfThen(UseAfterReturnIsEnabled, InsBefore, false);
3715 IRBuilder<> IRBIf(Term);
3716 StackMallocIdx = StackMallocSizeClass(LocalStackSize);
3717 assert(StackMallocIdx <= kMaxAsanStackMallocSizeClass);
3718 Value *FakeStackValue =
3719 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3720 ConstantInt::get(IntptrTy, LocalStackSize));
3721 IRB.SetInsertPoint(InsBefore);
3722 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3723 Term, ConstantInt::get(IntptrTy, 0));
3724 } else {
3725 // assert(ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode:Always)
3726 // void *FakeStack = __asan_stack_malloc_N(LocalStackSize);
3727 // void *LocalStackBase = (FakeStack) ? FakeStack :
3728 // alloca(LocalStackSize);
3729 StackMallocIdx = StackMallocSizeClass(LocalStackSize);
3730 FakeStackInt =
3731 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3732 ConstantInt::get(IntptrTy, LocalStackSize));
3733 }
3734 FakeStackPtr = IRB.CreateIntToPtr(FakeStackInt, PtrTy);
3735 Value *NoFakeStack =
3736 IRB.CreateICmpEQ(FakeStackInt, Constant::getNullValue(IntptrTy));
3737 Instruction *Term =
3738 SplitBlockAndInsertIfThen(NoFakeStack, InsBefore, false);
3739 IRBuilder<> IRBIf(Term);
3740 Value *AllocaValue =
3741 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca;
3742
3743 IRB.SetInsertPoint(InsBefore);
3744 LocalStackBase =
3745 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3746 IRB.CreateStore(LocalStackBase, LocalStackBaseAlloca);
3747 DIExprFlags |= DIExpression::DerefBefore;
3748 } else {
3749 // void *FakeStack = nullptr;
3750 // void *LocalStackBase = alloca(LocalStackSize);
3751 FakeStackInt = Constant::getNullValue(IntptrTy);
3752 FakeStackPtr = Constant::getNullValue(PtrTy);
3753 LocalStackBase =
3754 DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca;
3755 LocalStackBaseAlloca = LocalStackBase;
3756 }
3757
3758 // Replace Alloca instructions with base+offset.
3759 SmallVector<Value *> NewAllocaPtrs;
3760 for (const auto &Desc : SVD) {
3761 AllocaInst *AI = Desc.AI;
3762 replaceDbgDeclare(AI, LocalStackBaseAlloca, DIB, DIExprFlags, Desc.Offset);
3763 Value *NewAllocaPtr = IRB.CreatePtrAdd(
3764 LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset));
3765 if (NewAllocaPtr->getType() != AI->getType())
3766 NewAllocaPtr = IRB.CreateAddrSpaceCast(NewAllocaPtr, AI->getType());
3767 AI->replaceAllUsesWith(NewAllocaPtr);
3768 NewAllocaPtrs.push_back(NewAllocaPtr);
3769 }
3770
3771 // The left-most redzone has enough space for at least 4 pointers.
3772 // Write the Magic value to redzone[0].
3773 IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic),
3774 LocalStackBase);
3775 // Write the frame description constant to redzone[1].
3776 Value *BasePlus1 = IRB.CreatePtrAdd(
3777 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3778 GlobalVariable *StackDescriptionGlobal =
3779 createPrivateGlobalForString(*F.getParent(), DescriptionString,
3780 /*AllowMerging*/ true, genName("stack"));
3781 Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal, IntptrTy);
3782 IRB.CreateStore(Description, BasePlus1);
3783 // Write the PC to redzone[2].
3784 Value *BasePlus2 = IRB.CreatePtrAdd(
3785 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3786 IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2);
3787
3788 const auto &ShadowAfterScope = GetShadowBytesAfterScope(SVD, L);
3789
3790 // Poison the stack red zones at the entry.
3791 Value *ShadowBase =
3792 ASan.memToShadow(IRB.CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3793 // As mask we must use most poisoned case: red zones and after scope.
3794 // As bytes we can use either the same or just red zones only.
3795 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3796
3797 if (!StaticAllocaPoisonCallVec.empty()) {
3798 const auto &ShadowInScope = GetShadowBytes(SVD, L);
3799
3800 // Poison static allocas near lifetime intrinsics.
3801 for (const auto &APC : StaticAllocaPoisonCallVec) {
3802 const ASanStackVariableDescription &Desc = *AllocaToSVDMap[APC.AI];
3803 assert(Desc.Offset % L.Granularity == 0);
3804 size_t Begin = Desc.Offset / L.Granularity;
3805 size_t End = Begin + (APC.Size + L.Granularity - 1) / L.Granularity;
3806
3807 IRBuilder<> IRB(APC.InsBefore);
3808 copyToShadow(ShadowAfterScope,
3809 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3810 IRB, ShadowBase);
3811 }
3812 }
3813
3814 // Remove lifetime markers now that these are no longer allocas.
3815 for (Value *NewAllocaPtr : NewAllocaPtrs) {
3816 for (User *U : make_early_inc_range(NewAllocaPtr->users())) {
3817 auto *I = cast<Instruction>(U);
3818 if (I->isLifetimeStartOrEnd())
3819 I->eraseFromParent();
3820 }
3821 }
3822
3823 SmallVector<uint8_t, 64> ShadowClean(ShadowAfterScope.size(), 0);
3824 SmallVector<uint8_t, 64> ShadowAfterReturn;
3825
3826 // (Un)poison the stack before all ret instructions.
3827 for (Instruction *Ret : RetVec) {
3828 IRBuilder<> IRBRet(Ret);
3829 // Mark the current frame as retired.
3830 IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),
3831 LocalStackBase);
3832 if (DoStackMalloc) {
3833 assert(StackMallocIdx >= 0);
3834 // if FakeStack != 0 // LocalStackBase == FakeStack
3835 // // In use-after-return mode, poison the whole stack frame.
3836 // if StackMallocIdx <= 4
3837 // // For small sizes inline the whole thing:
3838 // memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
3839 // **SavedFlagPtr(FakeStack) = 0
3840 // else
3841 // __asan_stack_free_N(FakeStack, LocalStackSize)
3842 // else
3843 // <This is not a fake stack; unpoison the redzones>
3844 Value *Cmp =
3845 IRBRet.CreateICmpNE(FakeStackInt, Constant::getNullValue(IntptrTy));
3846 Instruction *ThenTerm, *ElseTerm;
3847 SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm);
3848
3849 IRBuilder<> IRBPoison(ThenTerm);
3850 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3851 int ClassSize = kMinStackMallocSize << StackMallocIdx;
3852 ShadowAfterReturn.resize(ClassSize / L.Granularity,
3854 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3855 ShadowBase);
3856 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3857 FakeStackPtr,
3858 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3859 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3860 IRBPoison.CreateStore(
3861 Constant::getNullValue(IRBPoison.getInt8Ty()),
3862 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3863 } else {
3864 // For larger frames call __asan_stack_free_*.
3865 RTCI.createRuntimeCall(
3866 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3867 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3868 }
3869
3870 IRBuilder<> IRBElse(ElseTerm);
3871 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3872 } else {
3873 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3874 }
3875 }
3876
3877 // We are done. Remove the old unused alloca instructions.
3878 for (auto *AI : AllocaVec)
3879 AI->eraseFromParent();
3880}
3881
3882void FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size,
3883 IRBuilder<> &IRB, bool DoPoison) {
3884 // For now just insert the call to ASan runtime.
3885 Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy);
3886 Value *SizeArg = ConstantInt::get(IntptrTy, Size);
3887 RTCI.createRuntimeCall(
3888 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3889 {AddrArg, SizeArg});
3890}
3891
3892// Handling llvm.lifetime intrinsics for a given %alloca:
3893// (1) collect all llvm.lifetime.xxx(%size, %value) describing the alloca.
3894// (2) if %size is constant, poison memory for llvm.lifetime.end (to detect
3895// invalid accesses) and unpoison it for llvm.lifetime.start (the memory
3896// could be poisoned by previous llvm.lifetime.end instruction, as the
3897// variable may go in and out of scope several times, e.g. in loops).
3898// (3) if we poisoned at least one %alloca in a function,
3899// unpoison the whole stack frame at function exit.
3900void FunctionStackPoisoner::handleDynamicAllocaCall(AllocaInst *AI) {
3901 IRBuilder<> IRB(AI);
3902
3903 const Align Alignment = std::max(Align(kAllocaRzSize), AI->getAlign());
3904 const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1;
3905
3906 Value *Zero = Constant::getNullValue(IntptrTy);
3907 Value *AllocaRzSize = ConstantInt::get(IntptrTy, kAllocaRzSize);
3908 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3909
3910 // Since we need to extend alloca with additional memory to locate
3911 // redzones, and OldSize is number of allocated blocks with
3912 // ElementSize size, get allocated memory size in bytes by
3913 // OldSize * ElementSize.
3914 Value *OldSize = IRB.CreateAllocationSize(IntptrTy, AI);
3915
3916 // PartialSize = OldSize % 32
3917 Value *PartialSize = IRB.CreateAnd(OldSize, AllocaRzMask);
3918
3919 // Misalign = kAllocaRzSize - PartialSize;
3920 Value *Misalign = IRB.CreateSub(AllocaRzSize, PartialSize);
3921
3922 // PartialPadding = Misalign != kAllocaRzSize ? Misalign : 0;
3923 Value *Cond = IRB.CreateICmpNE(Misalign, AllocaRzSize);
3924 Value *PartialPadding = IRB.CreateSelect(Cond, Misalign, Zero);
3925
3926 // AdditionalChunkSize = Alignment + PartialPadding + kAllocaRzSize
3927 // Alignment is added to locate left redzone, PartialPadding for possible
3928 // partial redzone and kAllocaRzSize for right redzone respectively.
3929 Value *AdditionalChunkSize = IRB.CreateAdd(
3930 ConstantInt::get(IntptrTy, Alignment.value() + kAllocaRzSize),
3931 PartialPadding);
3932
3933 Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize);
3934
3935 // Insert new alloca with new NewSize and Alignment params.
3936 AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize);
3937 NewAlloca->setAlignment(Alignment);
3938
3939 // NewAddress = Address + Alignment
3940 Value *NewAddress =
3941 IRB.CreateAdd(IRB.CreatePtrToInt(NewAlloca, IntptrTy),
3942 ConstantInt::get(IntptrTy, Alignment.value()));
3943
3944 // Insert __asan_alloca_poison call for new created alloca.
3945 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3946
3947 // Store the last alloca's address to DynamicAllocaLayout. We'll need this
3948 // for unpoisoning stuff.
3949 IRB.CreateStore(IRB.CreatePtrToInt(NewAlloca, IntptrTy), DynamicAllocaLayout);
3950
3951 Value *NewAddressPtr = IRB.CreateIntToPtr(NewAddress, AI->getType());
3952
3953 // Remove lifetime markers now that this is no longer an alloca.
3954 for (User *U : make_early_inc_range(AI->users())) {
3955 auto *I = cast<Instruction>(U);
3956 if (I->isLifetimeStartOrEnd())
3957 I->eraseFromParent();
3958 }
3959
3960 // Replace all uses of AddressReturnedByAlloca with NewAddressPtr.
3961 AI->replaceAllUsesWith(NewAddressPtr);
3962
3963 // We are done. Erase old alloca from parent.
3964 AI->eraseFromParent();
3965}
3966
3967// isSafeAccess returns true if Addr is always inbounds with respect to its
3968// base object. For example, it is a field access or an array access with
3969// constant inbounds index.
3970bool AddressSanitizer::isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
3971 Value *Addr, TypeSize TypeStoreSize) const {
3972 if (TypeStoreSize.isScalable())
3973 // TODO: We can use vscale_range to convert a scalable value to an
3974 // upper bound on the access size.
3975 return false;
3976
3977 SizeOffsetAPInt SizeOffset = ObjSizeVis.compute(Addr);
3978 if (!SizeOffset.bothKnown())
3979 return false;
3980
3981 uint64_t Size = SizeOffset.Size.getZExtValue();
3982 int64_t Offset = SizeOffset.Offset.getSExtValue();
3983
3984 // Three checks are required to ensure safety:
3985 // . Offset >= 0 (since the offset is given from the base ptr)
3986 // . Size >= Offset (unsigned)
3987 // . Size - Offset >= NeededSize (unsigned)
3988 return Offset >= 0 && Size >= uint64_t(Offset) &&
3989 Size - uint64_t(Offset) >= TypeStoreSize / 8;
3990}
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 bool isPointerPairOperand(Value *V, Type *IntptrTy)
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
static cl::opt< bool > ClOptimizeCallbacks("asan-optimize-callbacks", cl::desc("Optimize callbacks"), cl::Hidden, cl::init(false))
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(true))
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static cl::opt< int > ClShadowAddrSpace("asan-shadow-addr-space", cl::desc("Address space for pointers to the shadow map"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClInvalidPointerCmp("asan-detect-invalid-pointer-cmp", cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInvalidPointerSub("asan-detect-invalid-pointer-sub", cl::desc("Instrument - operations with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static cl::list< unsigned > ClAddrSpaces("asan-instrument-address-spaces", cl::desc("Only instrument variables in the specified address spaces."), cl::Hidden, cl::CommaSeparated, cl::callback([](const unsigned &AddrSpace) { SrcAddrSpaces.insert(AddrSpace);}))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
constexpr size_t kAccessSizeIndexShift
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
const char kAsanPoisonStackMemoryName[]
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isSupportedAddrspace(const Triple &TargetTriple, Value *Addr)
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static cl::opt< AsanDetectStackUseAfterReturnMode > ClUseAfterReturn("asan-use-after-return", cl::desc("Sets the mode of detection for stack-use-after-return."), cl::values(clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", "Never detect stack use after return."), clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, "runtime", "Detect stack use after return if " "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", "Always detect stack use after return.")), cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime))
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static const uintptr_t kCurrentStackFrameMagic
static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kPPC64_ShadowOffset64
static cl::opt< AsanCtorKind > ClConstructorKind("asan-constructor-kind", cl::desc("Sets the ASan constructor kind"), cl::values(clEnumValN(AsanCtorKind::None, "none", "No constructors"), clEnumValN(AsanCtorKind::Global, "global", "Use global constructors")), cl::init(AsanCtorKind::Global), cl::Hidden)
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
static const uint64_t kNetBSD_ShadowOffset64
const char kAsanPtrSub[]
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
static const uint64_t kWindowsShadowOffset32
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
static SmallSet< unsigned, 8 > SrcAddrSpaces
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const char kAsanReportErrorTemplate[]
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
static StringRef getAllocaName(AllocaInst *AI)
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
static const uintptr_t kRetiredStackFrameMagic
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:540
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp: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:1560
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
LLVM_ABI AddressSanitizerPass(const AddressSanitizerOptions &Options, bool UseGlobalGC=true, bool UseOdrIndicator=true, AsanDtorKind DestructorKind=AsanDtorKind::Global, AsanCtorKind ConstructorKind=AsanCtorKind::Global)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
bool isScalable() const
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Class to represent array types.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:446
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
bool isInlineAsm() const
Check if this call is an inline asm statement.
void setCannotMerge()
static LLVM_ABI CallBase * addOperandBundle(CallBase *CB, uint32_t ID, OperandBundleDef OB, InsertPosition InsertPt=nullptr)
Create a clone of CB with operand bundle OB added.
bool doesNotReturn() const
Determine if the call cannot return.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
@ Largest
The linker will choose the largest COMDAT.
Definition Comdat.h:39
@ SameSize
The data referenced by the COMDAT must be the same size.
Definition Comdat.h:41
@ Any
The linker may choose any COMDAT.
Definition Comdat.h:37
@ NoDeduplicate
No deduplication is performed.
Definition Comdat.h:40
@ ExactMatch
The data referenced by the COMDAT must be the same.
Definition Comdat.h:38
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
ConstantArray - Constant Array Declarations.
Definition Constants.h:590
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI bool isValueValidForType(Type *Ty, uint64_t V)
This static method returns true if the type Ty is big enough to represent the value V.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
DILocation * get() const
Get the underlying DILocation.
Definition DebugLoc.h:220
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
const BasicBlock & front() const
Definition Function.h:845
DISubprogram * getSubprogram() const
Get the attached subprogram.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
Definition Function.cpp:376
bool hasPersonalityFn() const
Check whether this function has a personality function.
Definition Function.h:890
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:356
const Constant * getAliasee() const
Definition GlobalAlias.h:87
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:692
LLVM_ABI void copyMetadata(const GlobalObject *Src, unsigned Offset)
Copy metadata from Src, adjusting offsets by Offset.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
Definition Globals.cpp:348
VisibilityTypes getVisibility() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
ThreadLocalMode getThreadLocalMode() const
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ CommonLinkage
Tentative definitions.
Definition GlobalValue.h:63
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
DLLStorageClassTypes getDLLStorageClass() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
Definition Globals.cpp:647
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNull=false)
Definition IRBuilder.h:2256
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1887
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:519
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2665
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1942
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Definition IRBuilder.h:663
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2305
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2418
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:176
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2246
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1540
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:534
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2100
BasicBlock * GetInsertBlock() const
Definition IRBuilder.h:175
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:539
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2394
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2019
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:477
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2555
Value * CreateNot(Value *V, const Twine &Name="")
Definition IRBuilder.h:1862
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2390
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1447
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
Definition IRBuilder.h:487
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1914
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1578
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1933
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1430
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2241
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition IRBuilder.h:2757
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2569
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2331
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:181
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:572
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1961
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1600
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:524
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1464
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2908
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition InlineAsm.cpp:43
Base class for instruction visitors.
Definition InstVisitor.h:78
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
iterator_range< user_iterator > users()
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
A wrapper class for inspecting calls to intrinsic functions.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
An instruction for reading from memory.
static Error ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
Parse the section specifier indicated by "Spec".
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition MDBuilder.cpp:48
Metadata node.
Definition Metadata.h:1081
ArrayRef< MDOperand > operands() const
Definition Metadata.h:1435
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1578
Tuple of metadata.
Definition Metadata.h:1495
This is the common base class for memset/memcpy/memmove.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase otherMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:159
Root of the metadata hierarchy.
Definition Metadata.h:64
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Evaluate the size and offset of an object pointed to by a Value* statically.
LLVM_ABI SizeOffsetAPInt compute(Value *V)
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition Analysis.h:171
Return a value (possibly void), from a function.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
LLVM_ABI bool stackAccessIsSafe(const Instruction &I) const
LLVM_ABI bool isSafe(const AllocaInst &AI) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
EltTy front() const
unsigned size() const
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
Definition Triple.h:997
bool isDriverKit() const
Is this an Apple DriverKit triple.
Definition Triple.h:707
bool isBPF() const
Tests whether the target is eBPF.
Definition Triple.h:1242
bool isOSNetBSD() const
Definition Triple.h:744
bool isAndroid() const
Tests whether the target is Android.
Definition Triple.h:910
bool isABIN32() const
Definition Triple.h:1230
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition Triple.h:1129
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:514
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition Triple.h:1118
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
Definition Triple.h:1124
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:777
@ UnknownObjectFormat
Definition Triple.h:421
bool isARM() const
Tests whether the target is ARM (little and big endian).
Definition Triple.h:1002
bool isOSLinux() const
Tests whether the OS is Linux.
Definition Triple.h:830
bool isAMDGPU() const
Definition Triple.h:994
bool isMacOSX() const
Is this a Mac OS X triple.
Definition Triple.h:681
bool isOSFreeBSD() const
Definition Triple.h:748
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition Triple.h:845
bool isWatchOS() const
Is this an Apple watchOS triple.
Definition Triple.h:696
bool isiOS() const
Is this an iOS triple.
Definition Triple.h:690
bool isPS() const
Tests whether the target is the PS4 or PS5 platform.
Definition Triple.h:907
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Definition Triple.h:1211
bool isOSFuchsia() const
Definition Triple.h:750
bool isOSHaiku() const
Tests whether the OS is Haiku.
Definition Triple.h:771
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
static LLVM_ABI ValueAsMetadata * get(Value *V)
Definition Metadata.cpp:514
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
Definition Value.cpp:1164
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:400
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
CallInst * Call
Changed
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void getInterestingMemoryOperands(Module &M, Instruction *I, SmallVectorImpl< InterestingMemoryOperand > &Interesting)
Get all the memory operands from the instruction that needs to be instrumented.
void instrumentAddress(Module &M, IRBuilder<> &IRB, Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, Align Alignment, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, bool Recover, int AsanScale, int AsanOffset)
Instrument the memory operand Addr.
uint64_t getRedzoneSizeForGlobal(int AsanScale, uint64_t SizeInBytes)
Given SizeInBytes of the Value to be instrunmented, Returns the redzone size corresponding to it.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
Definition MachO.h:131
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
cb< typename detail::callback_traits< F >::result_type, typename detail::callback_traits< F >::arg_type > callback(F CB)
LLVM_ABI uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
@ Offset
Definition DWP.cpp:577
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
LLVM_ABI GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, Twine NamePrefix="")
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
LLVM_ABI Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
AsanDetectStackUseAfterReturnMode
Mode of ASan detect stack use after return.
@ Always
Always detect stack use after return.
@ Never
Never detect stack use after return.
@ Runtime
Detect stack use after return if not disabled runtime with (ASAN_OPTIONS=detect_stack_use_after_retur...
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
Op::Description Desc
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
LLVM_ABI SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytes(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AsanDtorKind
Types of ASan module destructors supported.
@ Invalid
Not a valid destructor Kind.
@ Global
Append to llvm.global_dtors.
@ None
Do not emit any destructors for ASan.
LLVM_ABI ASanStackFrameLayout ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, uint64_t Granularity, uint64_t MinHeaderSize)
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ ModRef
The access may reference and may modify the value stored in memory.
Definition ModRef.h:36
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
@ ArgMem
Access to memory via argument pointers.
Definition ModRef.h:62
@ Other
Any other memory.
Definition ModRef.h:68
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
Definition ModRef.h:64
TargetTransformInfo TTI
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
OperandBundleDefT< Value * > OperandBundleDef
Definition AutoUpgrade.h:34
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
static const int kAsanStackUseAfterReturnMagic
LLVM_ABI void setGlobalVariableLargeSection(const Triple &TargetTriple, GlobalVariable &GV)
LLVM_ABI void removeASanIncompatibleFnAttributes(Function &F, bool ReadsArgMem)
Remove memory attributes that are incompatible with the instrumentation added by AddressSanitizer and...
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isModAndRefSet(const ModRefInfo MRI)
Definition ModRef.h:46
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
TinyPtrVector< BasicBlock * > ColorVector
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AsanCtorKind
Types of ASan module constructors supported.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition Local.cpp: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.