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