98#define DEBUG_TYPE "asan"
104 std::numeric_limits<uint64_t>::max();
145 "__asan_unregister_image_globals";
158 "__asan_stack_malloc_always_";
172 "__asan_option_detect_stack_use_after_return";
175 "__asan_shadow_memory_dynamic_address";
201 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
206 cl::desc(
"Enable recovery mode (continue-after-error)."),
210 "asan-guard-against-version-mismatch",
216 cl::desc(
"instrument read instructions"),
220 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
229 "asan-instrument-atomics",
239 "asan-always-slow-path",
244 "asan-force-dynamic-shadow",
245 cl::desc(
"Load shadow address into a local variable for each function"),
250 cl::desc(
"Access dynamic shadow through an ifunc global on "
251 "platforms that support this"),
256 cl::desc(
"Address space for pointers to the shadow map"),
260 "asan-with-ifunc-suppress-remat",
261 cl::desc(
"Suppress rematerialization of dynamic shadow address by passing "
262 "it through inline asm in prologue."),
270 "asan-max-ins-per-bb",
cl::init(10000),
271 cl::desc(
"maximal number of instructions to instrument in any given BB"),
278 "asan-max-inline-poisoning-size",
280 "Inline shadow poisoning for blocks up to the given size in bytes."),
284 "asan-use-after-return",
285 cl::desc(
"Sets the mode of detection for stack-use-after-return."),
288 "Never detect stack use after return."),
291 "Detect stack use after return if "
292 "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."),
294 "Always detect stack use after return.")),
298 cl::desc(
"Create redzones for byval "
299 "arguments (extra copy "
304 cl::desc(
"Check stack-use-after-scope"),
313 cl::desc(
"Handle C++ initializer order"),
317 "asan-detect-invalid-pointer-pair",
322 "asan-detect-invalid-pointer-cmp",
327 "asan-detect-invalid-pointer-sub",
332 "asan-realign-stack",
333 cl::desc(
"Realign stack to the value of this flag (power of two)"),
337 "asan-instrumentation-with-call-threshold",
338 cl::desc(
"If the function being instrumented contains more than "
339 "this number of memory accesses, use callbacks instead of "
340 "inline checks (-1 means never use callbacks)."),
344 "asan-memory-access-callback-prefix",
349 "asan-kernel-mem-intrinsic-prefix",
355 cl::desc(
"instrument dynamic allocas"),
359 "asan-skip-promotable-allocas",
364 "asan-constructor-kind",
365 cl::desc(
"Sets the ASan constructor kind"),
368 "Use global constructors")),
375 cl::desc(
"scale of asan shadow mapping"),
380 cl::desc(
"offset of asan shadow mapping [EXPERIMENTAL]"),
394 "asan-opt-same-temp",
cl::desc(
"Instrument the same temp just once"),
398 cl::desc(
"Don't instrument scalar globals"),
402 "asan-opt-stack",
cl::desc(
"Don't instrument scalar stack variables"),
406 "asan-stack-dynamic-alloca",
411 "asan-force-experiment",
417 cl::desc(
"Use private aliases for global variables"),
422 cl::desc(
"Use odr indicators to improve ODR reporting"),
427 cl::desc(
"Use linker features to support dead "
428 "code stripping of globals"),
435 cl::desc(
"Place ASan constructors in comdat sections"),
439 "asan-destructor-kind",
440 cl::desc(
"Sets the ASan destructor kind. The default is to use the value "
441 "provided to the pass constructor"),
444 "Use global destructors")),
449 "asan-instrument-address-spaces",
450 cl::desc(
"Only instrument variables in the specified address spaces."),
472STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
473STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
475 "Number of optimized accesses to global vars");
477 "Number of optimized accesses to stack vars");
486struct ShadowMapping {
497 bool IsAndroid = TargetTriple.
isAndroid();
500 bool IsMacOS = TargetTriple.
isMacOSX();
503 bool IsPS = TargetTriple.
isPS();
509 bool IsMIPSN32ABI = TargetTriple.
isABIN32();
510 bool IsMIPS32 = TargetTriple.
isMIPS32();
511 bool IsMIPS64 = TargetTriple.
isMIPS64();
512 bool IsArmOrThumb = TargetTriple.
isARM() || TargetTriple.
isThumb();
519 bool IsAMDGPU = TargetTriple.
isAMDGPU();
521 bool IsWasm = TargetTriple.
isWasm();
522 bool IsBPF = TargetTriple.
isBPF();
524 ShadowMapping Mapping;
531 if (LongSize == 32) {
534 else if (IsMIPSN32ABI)
560 else if (IsFreeBSD && IsAArch64)
562 else if (IsFreeBSD && !IsMIPS64) {
567 }
else if (IsNetBSD) {
574 else if (IsLinux && IsX86_64) {
580 }
else if (IsWindows && (IsX86_64 || IsAArch64)) {
586 else if (IsMacOS && IsAArch64)
590 else if (IsLoongArch64)
597 else if (IsHaiku && IsX86_64)
619 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
620 !IsRISCV64 && !IsLoongArch64 &&
621 !(Mapping.Offset & (Mapping.Offset - 1)) &&
623 Mapping.InGlobal =
ClWithIfunc && IsAndroid && IsArmOrThumb;
630 int *MappingScale,
bool *OrShadowOffset) {
632 *ShadowBase = Mapping.Offset;
633 *MappingScale = Mapping.Scale;
634 *OrShadowOffset = Mapping.OrShadowOffset;
655 if (!
F.getMemoryEffects()
657 .doesNotAccessMemory() &&
659 F.setMemoryEffects(
F.getMemoryEffects() |
667 F.setMemoryEffects(
F.getMemoryEffects() |
672 if (
A.hasAttribute(Attribute::WriteOnly)) {
673 A.removeAttr(Attribute::WriteOnly);
681 F.addFnAttr(Attribute::NoBuiltin);
702 return std::max(32U, 1U << MappingScale);
718class AsanFunctionInserter {
720 AsanFunctionInserter(
Module &M) :
M(
M) {}
722 template <
typename... ArgTypes>
723 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
724 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
737class RuntimeCallInserter {
739 bool TrackInsertedCalls =
false;
743 RuntimeCallInserter(Function &Fn) : OwnerFn(&Fn) {
745 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
746 if (isScopedEHPersonality(Personality))
747 TrackInsertedCalls = true;
751 ~RuntimeCallInserter() {
752 if (InsertedCalls.
empty())
754 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
756 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
757 for (CallInst *CI : InsertedCalls) {
759 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
761 "Instruction doesn't belong to the expected Function!");
769 if (Colors.
size() != 1) {
771 "Instruction's BasicBlock is not monochromatic");
778 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
782 OB, CI->getIterator());
783 NewCall->copyMetadata(*CI);
784 CI->replaceAllUsesWith(NewCall);
785 CI->eraseFromParent();
790 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
792 const Twine &
Name =
"") {
795 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
796 if (TrackInsertedCalls)
797 InsertedCalls.push_back(Inst);
803struct AddressSanitizer {
804 AddressSanitizer(
Module &M,
const StackSafetyGlobalInfo *SSGI,
805 int InstrumentationWithCallsThreshold,
806 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
807 bool Recover =
false,
bool UseAfterScope =
false,
809 AsanDetectStackUseAfterReturnMode::Runtime)
818 InstrumentationWithCallsThreshold(
821 : InstrumentationWithCallsThreshold),
824 : MaxInlinePoisoningSize) {
825 C = &(
M.getContext());
826 DL = &
M.getDataLayout();
827 LongSize =
M.getDataLayout().getPointerSizeInBits();
828 IntptrTy = Type::getIntNTy(*
C, LongSize);
829 PtrTy = PointerType::getUnqual(*
C);
831 TargetTriple =
M.getTargetTriple();
835 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
843 bool isInterestingAlloca(
const AllocaInst &AI);
845 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
847 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
848 const TargetTransformInfo *
TTI);
850 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
851 InterestingMemoryOperand &O,
bool UseCalls,
852 const DataLayout &
DL, RuntimeCallInserter &RTCI);
853 void instrumentPointerComparisonOrSubtraction(Instruction *
I,
854 RuntimeCallInserter &RTCI);
856 Value *Addr, MaybeAlign Alignment,
857 uint32_t TypeStoreSize,
bool IsWrite,
858 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
859 RuntimeCallInserter &RTCI);
860 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
861 Instruction *InsertBefore,
Value *Addr,
862 uint32_t TypeStoreSize,
bool IsWrite,
863 Value *SizeArgument);
866 void instrumentUnusualSizeOrAlignment(Instruction *
I,
867 Instruction *InsertBefore,
Value *Addr,
868 TypeSize TypeStoreSize,
bool IsWrite,
869 Value *SizeArgument,
bool UseCalls,
871 RuntimeCallInserter &RTCI);
872 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
875 MaybeAlign Alignment,
unsigned Granularity,
876 Type *OpType,
bool IsWrite,
877 Value *SizeArgument,
bool UseCalls,
878 uint32_t Exp, RuntimeCallInserter &RTCI);
880 Value *ShadowValue, uint32_t TypeStoreSize);
882 bool IsWrite,
size_t AccessSizeIndex,
883 Value *SizeArgument, uint32_t Exp,
884 RuntimeCallInserter &RTCI);
885 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
887 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
888 bool instrumentFunction(Function &
F,
const TargetLibraryInfo *TLI,
889 const TargetTransformInfo *
TTI);
890 bool maybeInsertAsanInitAtFunctionEntry(Function &
F);
891 bool maybeInsertDynamicShadowAtFunctionEntry(Function &
F);
892 void markEscapedLocalAllocas(Function &
F);
893 void markCatchParametersAsUninteresting(Function &
F);
896 friend struct FunctionStackPoisoner;
898 void initializeCallbacks(
const TargetLibraryInfo *TLI);
900 bool LooksLikeCodeInBug11395(Instruction *
I);
901 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
902 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
903 TypeSize TypeStoreSize)
const;
906 struct FunctionStateRAII {
907 AddressSanitizer *
Pass;
909 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
911 "last pass forgot to clear cache");
915 ~FunctionStateRAII() {
916 Pass->LocalDynamicShadow =
nullptr;
917 Pass->ProcessedAllocas.clear();
922 AsanFunctionInserter Inserter;
924 const DataLayout *
DL;
934 ShadowMapping Mapping;
935 FunctionCallee AsanHandleNoReturnFunc;
936 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
944 FunctionCallee AsanErrorCallbackSized[2][2];
945 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
947 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
948 Value *LocalDynamicShadow =
nullptr;
949 const StackSafetyGlobalInfo *SSGI;
950 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
952 FunctionCallee AMDGPUAddressShared;
953 FunctionCallee AMDGPUAddressPrivate;
954 int InstrumentationWithCallsThreshold;
955 uint32_t MaxInlinePoisoningSize;
958class ModuleAddressSanitizer {
960 ModuleAddressSanitizer(
Module &M,
bool InsertVersionCheck,
961 bool CompileKernel =
false,
bool Recover =
false,
962 bool UseGlobalsGC =
true,
bool UseOdrIndicator =
true,
970 : InsertVersionCheck),
972 UseGlobalsGC(UseGlobalsGC &&
ClUseGlobalsGC && !this->CompileKernel),
987 UseCtorComdat(UseGlobalsGC &&
ClWithComdat && !this->CompileKernel),
988 DestructorKind(DestructorKind),
992 C = &(
M.getContext());
993 int LongSize =
M.getDataLayout().getPointerSizeInBits();
994 IntptrTy = Type::getIntNTy(*
C, LongSize);
995 PtrTy = PointerType::getUnqual(*
C);
996 TargetTriple =
M.getTargetTriple();
1001 assert(this->DestructorKind != AsanDtorKind::Invalid);
1004 bool instrumentModule();
1007 void initializeCallbacks();
1009 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
1016 const std::string &UniqueModuleId);
1021 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
1025 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
1026 StringRef OriginalName);
1027 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
1028 StringRef InternalSuffix);
1031 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
1032 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
1033 bool ShouldUseMachOGlobalsSection()
const;
1034 StringRef getGlobalMetadataSection()
const;
1035 void poisonOneInitializer(Function &GlobalInit);
1036 void createInitializerPoisonCalls();
1037 uint64_t getMinRedzoneSizeForGlobal()
const {
1041 int GetAsanVersion()
const;
1042 GlobalVariable *getOrCreateModuleName();
1045 AsanFunctionInserter Inserter;
1047 bool InsertVersionCheck;
1050 bool UsePrivateAlias;
1051 bool UseOdrIndicator;
1058 Triple TargetTriple;
1059 ShadowMapping Mapping;
1060 FunctionCallee AsanPoisonGlobals;
1061 FunctionCallee AsanUnpoisonGlobals;
1062 FunctionCallee AsanRegisterGlobals;
1063 FunctionCallee AsanUnregisterGlobals;
1064 FunctionCallee AsanRegisterImageGlobals;
1065 FunctionCallee AsanUnregisterImageGlobals;
1066 FunctionCallee AsanRegisterElfGlobals;
1067 FunctionCallee AsanUnregisterElfGlobals;
1069 Function *AsanCtorFunction =
nullptr;
1070 Function *AsanDtorFunction =
nullptr;
1071 GlobalVariable *ModuleName =
nullptr;
1083struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
1085 AddressSanitizer &ASan;
1086 RuntimeCallInserter &RTCI;
1091 ShadowMapping Mapping;
1095 SmallVector<Instruction *, 8> RetVec;
1099 FunctionCallee AsanSetShadowFunc[0x100] = {};
1100 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
1101 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
1104 struct AllocaPoisonCall {
1105 IntrinsicInst *InsBefore;
1115 AllocaInst *DynamicAllocaLayout =
nullptr;
1116 IntrinsicInst *LocalEscapeCall =
nullptr;
1118 bool HasInlineAsm =
false;
1119 bool HasReturnsTwiceCall =
false;
1122 FunctionStackPoisoner(Function &
F, AddressSanitizer &ASan,
1123 RuntimeCallInserter &RTCI)
1124 :
F(
F), ASan(ASan), RTCI(RTCI),
1126 IntptrTy(ASan.IntptrTy),
1128 Mapping(ASan.Mapping),
1136 copyArgsPassedByValToAllocas();
1141 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
1143 initializeCallbacks(*
F.getParent());
1145 processDynamicAllocas();
1146 processStaticAllocas();
1157 void copyArgsPassedByValToAllocas();
1162 void processStaticAllocas();
1163 void processDynamicAllocas();
1165 void createDynamicAllocasInitStorage();
1170 void visitReturnInst(ReturnInst &RI) {
1171 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
1178 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
1181 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
1183 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
1184 Value *SavedStack) {
1193 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
1199 RTCI.createRuntimeCall(
1200 IRB, AsanAllocasUnpoisonFunc,
1201 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
1205 void unpoisonDynamicAllocas() {
1206 for (Instruction *Ret : RetVec)
1207 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
1209 for (Instruction *StackRestoreInst : StackRestoreVec)
1210 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
1211 StackRestoreInst->getOperand(0));
1224 void handleDynamicAllocaCall(AllocaInst *AI);
1227 void visitAllocaInst(AllocaInst &AI) {
1232 (STy && STy->containsHomogeneousScalableVectorTypes())) {
1236 if (AllocaVec.
empty())
1252 void visitIntrinsicInst(IntrinsicInst &
II) {
1254 if (
ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
1255 if (
ID == Intrinsic::localescape) LocalEscapeCall = &
II;
1256 if (!ASan.UseAfterScope)
1258 if (!
II.isLifetimeStartOrEnd())
1263 if (!AI || !ASan.isInterestingAlloca(*AI))
1273 bool DoPoison = (
ID == Intrinsic::lifetime_end);
1274 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
1276 StaticAllocaPoisonCallVec.
push_back(APC);
1278 DynamicAllocaPoisonCallVec.
push_back(APC);
1281 void visitCallBase(CallBase &CB) {
1283 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1284 HasReturnsTwiceCall |= CI->canReturnTwice();
1289 void initializeCallbacks(
Module &M);
1294 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1296 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1299 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1300 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1305 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1308 Instruction *ThenTerm,
Value *ValueIfFalse);
1316 OS, MapClassName2PassName);
1318 if (Options.CompileKernel)
1320 if (Options.UseAfterScope)
1321 OS <<
"use-after-scope";
1329 : Options(Options), UseGlobalGC(UseGlobalGC),
1330 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1331 ConstructorKind(ConstructorKind) {}
1340 ModuleAddressSanitizer ModuleSanitizer(
1341 M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
1342 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
1354 if (
F.getName().starts_with(
"__asan_"))
1356 if (
F.isPresplitCoroutine())
1358 AddressSanitizer FunctionSanitizer(
1359 M, SSGI, Options.InstrumentationWithCallsThreshold,
1360 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1361 Options.UseAfterScope, Options.UseAfterReturn);
1364 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1366 Modified |= ModuleSanitizer.instrumentModule();
1387 if (
G->getName().starts_with(
"llvm.") ||
1389 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1391 G->getName().starts_with(
"__llvm_rtti_proxy"))
1407 if (AddrSpace == 3 || AddrSpace == 5)
1422 return AddrSpace == 0;
1427 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1428 if (Mapping.Offset == 0)
return Shadow;
1431 if (LocalDynamicShadow)
1432 ShadowBase = LocalDynamicShadow;
1434 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1435 if (Mapping.OrShadowOffset)
1436 return IRB.
CreateOr(Shadow, ShadowBase);
1438 return IRB.
CreateAdd(Shadow, ShadowBase);
1443 RuntimeCallInserter &RTCI) {
1446 RTCI.createRuntimeCall(
1452 RTCI.createRuntimeCall(
1458 MI->eraseFromParent();
1462bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1463 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1466 return It->getSecond();
1468 bool IsInteresting =
1481 !(SSGI && SSGI->
isSafe(AI)));
1483 It->second = IsInteresting;
1484 return IsInteresting;
1514void AddressSanitizer::getInterestingMemoryOperands(
1518 if (LocalDynamicShadow ==
I)
1524 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1525 LI->getType(), LI->getAlign());
1530 SI->getValueOperand()->getType(),
SI->getAlign());
1534 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1535 RMW->getValOperand()->getType(), std::nullopt);
1539 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1540 XCHG->getCompareOperand()->getType(),
1543 switch (CI->getIntrinsicID()) {
1544 case Intrinsic::masked_load:
1545 case Intrinsic::masked_store:
1546 case Intrinsic::masked_gather:
1547 case Intrinsic::masked_scatter: {
1548 bool IsWrite = CI->getType()->isVoidTy();
1550 unsigned OpOffset = IsWrite ? 1 : 0;
1554 auto BasePtr = CI->getOperand(OpOffset);
1555 if (ignoreAccess(
I, BasePtr))
1557 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1559 Value *
Mask = CI->getOperand(1 + OpOffset);
1560 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1563 case Intrinsic::masked_expandload:
1564 case Intrinsic::masked_compressstore: {
1565 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1566 unsigned OpOffset = IsWrite ? 1 : 0;
1569 auto BasePtr = CI->getOperand(OpOffset);
1570 if (ignoreAccess(
I, BasePtr))
1573 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1576 Value *
Mask = CI->getOperand(1 + OpOffset);
1579 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1580 Value *EVL =
IB.CreateAddReduce(ExtMask);
1581 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1582 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1586 case Intrinsic::vp_load:
1587 case Intrinsic::vp_store:
1588 case Intrinsic::experimental_vp_strided_load:
1589 case Intrinsic::experimental_vp_strided_store: {
1591 unsigned IID = CI->getIntrinsicID();
1592 bool IsWrite = CI->getType()->isVoidTy();
1595 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1596 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1597 MaybeAlign Alignment = VPI->getOperand(PtrOpNo)->getPointerAlignment(*
DL);
1598 Value *Stride =
nullptr;
1599 if (IID == Intrinsic::experimental_vp_strided_store ||
1600 IID == Intrinsic::experimental_vp_strided_load) {
1601 Stride = VPI->getOperand(PtrOpNo + 1);
1608 Alignment =
Align(1);
1610 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1611 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1615 case Intrinsic::vp_gather:
1616 case Intrinsic::vp_scatter: {
1618 unsigned IID = CI->getIntrinsicID();
1619 bool IsWrite = IID == Intrinsic::vp_scatter;
1622 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1623 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1624 MaybeAlign Alignment = VPI->getPointerAlignment();
1625 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1626 VPI->getMaskParam(),
1627 VPI->getVectorLengthParam());
1633 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1637 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1639 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1641 Type *Ty = CI->getParamByValType(ArgNo);
1657 if (!Cmp->isRelational())
1671 if (BO->getOpcode() != Instruction::Sub)
1684 if (!
G->hasInitializer())
1687 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1693void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1697 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1698 for (
Value *&i : Param) {
1699 if (i->getType()->isPointerTy())
1702 RTCI.createRuntimeCall(IRB,
F, Param);
1708 TypeSize TypeStoreSize,
bool IsWrite,
1709 Value *SizeArgument,
bool UseCalls,
1710 uint32_t Exp, RuntimeCallInserter &RTCI) {
1715 switch (FixedSize) {
1721 if (!Alignment || *Alignment >= Granularity ||
1722 *Alignment >= FixedSize / 8)
1723 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1724 FixedSize, IsWrite,
nullptr, UseCalls,
1728 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1729 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1732void AddressSanitizer::instrumentMaskedLoadOrStore(
1735 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1736 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1737 RuntimeCallInserter &RTCI) {
1739 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1740 auto Zero = ConstantInt::get(IntptrTy, 0);
1748 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1750 IB.SetInsertPoint(LoopInsertBefore);
1752 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1755 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1756 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1758 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1763 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1767 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1768 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1769 if (MaskElemC->isZero())
1775 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1776 MaskElem, &*IRB.GetInsertPoint(), false);
1777 IRB.SetInsertPoint(ThenTerm);
1780 Value *InstrumentedAddress;
1783 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1784 "Expected vector of pointer.");
1785 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1786 }
else if (Stride) {
1793 Alignment, Granularity, ElemTypeSize, IsWrite,
1794 SizeArgument, UseCalls, Exp, RTCI);
1801 RuntimeCallInserter &RTCI) {
1802 Value *Addr =
O.getPtr();
1822 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1823 NumOptimizedAccessesToGlobalVar++;
1831 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1832 NumOptimizedAccessesToStackVar++;
1838 NumInstrumentedWrites++;
1840 NumInstrumentedReads++;
1842 if (
O.MaybeByteOffset) {
1847 if (TargetTriple.isRISCV()) {
1852 static_cast<unsigned>(LongSize)) {
1861 unsigned Granularity = 1 << Mapping.Scale;
1863 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1864 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1865 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1866 UseCalls, Exp, RTCI);
1869 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1870 UseCalls, Exp, RTCI);
1875 Value *Addr,
bool IsWrite,
1876 size_t AccessSizeIndex,
1877 Value *SizeArgument,
1879 RuntimeCallInserter &RTCI) {
1885 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1886 {Addr, SizeArgument});
1888 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1889 {Addr, SizeArgument, ExpVal});
1892 Call = RTCI.createRuntimeCall(
1893 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1895 Call = RTCI.createRuntimeCall(
1896 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1905 uint32_t TypeStoreSize) {
1906 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1908 Value *LastAccessedByte =
1909 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1911 if (TypeStoreSize / 8 > 1)
1913 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1916 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1921Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1923 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1930 return InsertBefore;
1935 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1937 Value *AddrSpaceZeroLanding =
1940 return InsertBefore;
1955 Trm->getParent()->setName(
"asan.report");
1966void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1969 uint32_t TypeStoreSize,
bool IsWrite,
1970 Value *SizeArgument,
bool UseCalls,
1972 RuntimeCallInserter &RTCI) {
1973 if (TargetTriple.isAMDGPU()) {
1974 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1975 TypeStoreSize, IsWrite, SizeArgument);
1984 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1987 ConstantInt::get(
Int32Ty, AccessInfo.Packed)});
1994 RTCI.createRuntimeCall(
1995 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1997 RTCI.createRuntimeCall(
1998 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1999 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
2006 Value *ShadowPtr = memToShadow(AddrLong, IRB);
2007 const uint64_t ShadowAlign =
2008 std::max<uint64_t>(Alignment.
valueOrOne().
value() >> Mapping.Scale, 1);
2013 size_t Granularity = 1ULL << Mapping.Scale;
2016 bool GenSlowPath = (
ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
2018 if (TargetTriple.isAMDGCN()) {
2020 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2023 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2024 }
else if (GenSlowPath) {
2031 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2046 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2055void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2057 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
2058 uint32_t Exp, RuntimeCallInserter &RTCI) {
2066 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2069 RTCI.createRuntimeCall(
2070 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2084void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
2090 Value *ModuleNameAddr =
2092 IRB.
CreateCall(AsanPoisonGlobals, ModuleNameAddr);
2095 for (
auto &BB : GlobalInit)
2100void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2120 poisonOneInitializer(*
F);
2126ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
2131 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
2143bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
2144 Type *Ty =
G->getValueType();
2147 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
2149 if (!Ty->
isSized())
return false;
2150 if (!
G->hasInitializer())
return false;
2157 if (
G->isThreadLocal())
return false;
2159 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
2165 if (!TargetTriple.isOSBinFormatCOFF()) {
2166 if (!
G->hasExactDefinition() ||
G->hasComdat())
2170 if (
G->isInterposable())
2174 if (
G->hasAvailableExternallyLinkage())
2181 switch (
C->getSelectionKind()) {
2192 if (
G->hasSection()) {
2202 if (Section ==
"llvm.metadata")
return false;
2209 if (
Section.starts_with(
".preinit_array") ||
2210 Section.starts_with(
".init_array") ||
2211 Section.starts_with(
".fini_array")) {
2217 if (TargetTriple.isOSBinFormatELF()) {
2231 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2232 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2237 if (TargetTriple.isOSBinFormatMachO()) {
2239 unsigned TAA = 0, StubSize = 0;
2242 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2247 if (ParsedSegment ==
"__OBJC" ||
2248 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2260 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2273 if (CompileKernel) {
2276 if (
G->getName().starts_with(
"__"))
2286bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2287 if (!TargetTriple.isOSBinFormatMachO())
2290 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2292 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2294 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2296 if (TargetTriple.isDriverKit())
2298 if (TargetTriple.isXROS())
2304StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2305 switch (TargetTriple.getObjectFormat()) {
2315 "ModuleAddressSanitizer not implemented for object file format");
2322void ModuleAddressSanitizer::initializeCallbacks() {
2328 AsanUnpoisonGlobals =
2332 AsanRegisterGlobals = Inserter.insertFunction(
2334 AsanUnregisterGlobals = Inserter.insertFunction(
2339 AsanRegisterImageGlobals = Inserter.insertFunction(
2341 AsanUnregisterImageGlobals = Inserter.insertFunction(
2344 AsanRegisterElfGlobals =
2346 IntptrTy, IntptrTy, IntptrTy);
2347 AsanUnregisterElfGlobals =
2349 IntptrTy, IntptrTy, IntptrTy);
2354void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2359 if (!
G->hasName()) {
2363 G->setName(
genName(
"anon_global"));
2366 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2367 std::string
Name = std::string(
G->getName());
2368 Name += InternalSuffix;
2369 C =
M.getOrInsertComdat(Name);
2371 C =
M.getOrInsertComdat(
G->getName());
2377 if (TargetTriple.isOSBinFormatCOFF()) {
2379 if (
G->hasPrivateLinkage())
2392ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2394 auto Linkage = TargetTriple.isOSBinFormatMachO()
2400 Metadata->setSection(getGlobalMetadataSection());
2407Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2411 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2419void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2423 auto &
DL =
M.getDataLayout();
2426 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2427 Constant *Initializer = MetadataInitializers[i];
2431 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2437 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2439 "global metadata will not be padded appropriately");
2442 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2447 if (!MetadataGlobals.empty())
2451void ModuleAddressSanitizer::instrumentGlobalsELF(
2454 const std::string &UniqueModuleId) {
2461 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2464 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2467 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2469 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2472 if (UseComdatForGlobalsGC)
2473 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2478 if (!MetadataGlobals.empty())
2495 "__start_" + getGlobalMetadataSection());
2499 "__stop_" + getGlobalMetadataSection());
2513 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2520void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2531 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2532 Constant *Initializer = MetadataInitializers[i];
2538 auto LivenessBinder =
2543 Twine(
"__asan_binder_") +
G->getName());
2544 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2545 LivenessGlobals[i] = Liveness;
2552 if (!LivenessGlobals.empty())
2574 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2579void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2583 unsigned N = ExtendedGlobals.
size();
2593 if (Mapping.Scale > 3)
2594 AllGlobals->setAlignment(
Align(1ULL << Mapping.Scale));
2599 ConstantInt::get(IntptrTy,
N)});
2605 IrbDtor.CreateCall(AsanUnregisterGlobals,
2607 ConstantInt::get(IntptrTy,
N)});
2616void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2621 if (CompileKernel) {
2622 for (
auto &GA :
M.aliases()) {
2624 AliasedGlobalExclusions.
insert(GV);
2629 for (
auto &
G :
M.globals()) {
2630 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2634 size_t n = GlobalsToChange.
size();
2635 auto &
DL =
M.getDataLayout();
2649 IntptrTy, IntptrTy, IntptrTy);
2653 for (
size_t i = 0; i < n; i++) {
2657 if (
G->hasSanitizerMetadata())
2658 MD =
G->getSanitizerMetadata();
2663 std::string NameForGlobal =
G->getName().str();
2668 Type *Ty =
G->getValueType();
2669 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2682 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2683 G->getThreadLocalMode(),
G->getAddressSpace());
2693 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2696 if (Seq && Seq->isCString())
2697 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2704 G->replaceAllUsesWith(NewGlobal);
2706 G->eraseFromParent();
2707 NewGlobals[i] = NewGlobal;
2712 bool CanUsePrivateAliases =
2713 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2714 TargetTriple.isOSBinFormatWasm();
2715 if (CanUsePrivateAliases && UsePrivateAlias) {
2718 InstrumentedGlobal =
2725 }
else if (UseOdrIndicator) {
2728 auto *ODRIndicatorSym =
2737 ODRIndicatorSym->setAlignment(
Align(1));
2744 ConstantInt::get(IntptrTy, SizeInBytes),
2745 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2748 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2753 Initializers[i] = Initializer;
2759 for (
size_t i = 0; i < n; i++) {
2761 if (
G->getName().empty())
continue;
2766 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2773 }
else if (n == 0) {
2776 *CtorComdat = TargetTriple.isOSBinFormatELF();
2778 *CtorComdat =
false;
2779 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2780 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2781 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2782 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2784 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2790 createInitializerPoisonCalls();
2796ModuleAddressSanitizer::getRedzoneSizeForGlobal(uint64_t SizeInBytes)
const {
2797 constexpr uint64_t kMaxRZ = 1 << 18;
2798 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2801 if (SizeInBytes <= MinRZ / 2) {
2805 RZ = MinRZ - SizeInBytes;
2808 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2811 if (SizeInBytes % MinRZ)
2812 RZ += MinRZ - (SizeInBytes % MinRZ);
2815 assert((RZ + SizeInBytes) % MinRZ == 0);
2820int ModuleAddressSanitizer::GetAsanVersion()
const {
2821 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2822 bool isAndroid =
M.getTargetTriple().isAndroid();
2826 Version += (LongSize == 32 && isAndroid);
2841bool ModuleAddressSanitizer::instrumentModule() {
2842 initializeCallbacks();
2850 if (CompileKernel) {
2855 std::string AsanVersion = std::to_string(GetAsanVersion());
2856 std::string VersionCheckName =
2858 std::tie(AsanCtorFunction, std::ignore) =
2861 {}, VersionCheckName);
2865 bool CtorComdat =
true;
2868 if (AsanCtorFunction) {
2869 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2870 instrumentGlobals(IRB, &CtorComdat);
2873 instrumentGlobals(IRB, &CtorComdat);
2882 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2883 if (AsanCtorFunction) {
2887 if (AsanDtorFunction) {
2892 if (AsanCtorFunction)
2894 if (AsanDtorFunction)
2905 for (
int Exp = 0;
Exp < 2;
Exp++) {
2906 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2907 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2908 const std::string ExpStr =
Exp ?
"exp_" :
"";
2909 const std::string EndingStr = Recover ?
"_noabort" :
"";
2919 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2920 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2921 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2924 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2928 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2929 Inserter.insertFunction(
2934 AccessSizeIndex++) {
2935 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2936 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2937 Inserter.insertFunction(
2941 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2942 Inserter.insertFunction(
2949 const std::string MemIntrinCallbackPrefix =
2953 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2954 PtrTy, PtrTy, PtrTy, IntptrTy);
2955 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2956 PtrTy, PtrTy, PtrTy, IntptrTy);
2958 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
2963 AsanHandleNoReturnFunc =
2966 AsanPtrCmpFunction =
2968 AsanPtrSubFunction =
2970 if (Mapping.InGlobal)
2971 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
2974 AMDGPUAddressShared =
2980bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2988 if (
F.getName().contains(
" load]")) {
2998bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
3004 if (Mapping.InGlobal) {
3012 LocalDynamicShadow =
3013 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
3015 LocalDynamicShadow =
3019 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
3021 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
3026void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
3031 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
3035 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
3041 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
3043 for (
Value *Arg :
II->args()) {
3046 "non-static alloca arg to localescape");
3047 ProcessedAllocas[AI] =
false;
3056void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
3062 for (
Value *Operand : CatchPad->arg_operands())
3064 ProcessedAllocas[AI] =
false;
3070bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
3071 bool ShouldInstrument =
3075 return !ShouldInstrument;
3078bool AddressSanitizer::instrumentFunction(
Function &
F,
3081 bool FunctionModified =
false;
3084 if (
F.hasFnAttribute(Attribute::Naked))
3085 return FunctionModified;
3090 if (maybeInsertAsanInitAtFunctionEntry(
F))
3091 FunctionModified =
true;
3094 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
3096 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3097 return FunctionModified;
3101 initializeCallbacks(TLI);
3103 FunctionStateRAII CleanupObj(
this);
3105 RuntimeCallInserter RTCI(
F);
3107 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
3111 markEscapedLocalAllocas(
F);
3113 if (TargetTriple.isOSWindows())
3114 markCatchParametersAsUninteresting(
F);
3126 for (
auto &BB :
F) {
3128 TempsToInstrument.
clear();
3129 int NumInsnsPerBB = 0;
3130 for (
auto &Inst : BB) {
3131 if (LooksLikeCodeInBug11395(&Inst))
return false;
3138 if (!InterestingOperands.
empty()) {
3139 for (
auto &Operand : InterestingOperands) {
3141 Value *Ptr = Operand.getPtr();
3145 if (Operand.MaybeMask) {
3146 if (TempsToInstrument.
count(Ptr))
3149 if (!TempsToInstrument.
insert(Ptr).second)
3153 OperandsToInstrument.
push_back(Operand);
3160 PointerComparisonsOrSubtracts.
push_back(&Inst);
3168 TempsToInstrument.
clear();
3179 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3180 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
3181 (
unsigned)InstrumentationWithCallsThreshold);
3186 int NumInstrumented = 0;
3187 for (
auto &Operand : OperandsToInstrument) {
3188 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3189 instrumentMop(ObjSizeVis, Operand, UseCalls,
3190 F.getDataLayout(), RTCI);
3191 FunctionModified =
true;
3193 for (
auto *Inst : IntrinToInstrument) {
3194 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3195 instrumentMemIntrinsic(Inst, RTCI);
3196 FunctionModified =
true;
3199 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3200 bool ChangedStack = FSP.runOnFunction();
3204 for (
auto *CI : NoReturnCalls) {
3206 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3209 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3210 instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3211 FunctionModified =
true;
3214 if (ChangedStack || !NoReturnCalls.empty())
3215 FunctionModified =
true;
3217 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3220 return FunctionModified;
3226bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3227 if (LongSize != 32)
return false;
3236void FunctionStackPoisoner::initializeCallbacks(
Module &) {
3240 const char *MallocNameTemplate =
3245 std::string Suffix =
itostr(Index);
3246 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3247 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3248 AsanStackFreeFunc[
Index] =
3253 if (ASan.UseAfterScope) {
3254 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3256 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3260 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3261 0xf3, 0xf5, 0xf8}) {
3262 std::ostringstream
Name;
3264 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3265 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3269 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3271 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3277 size_t Begin,
size_t End,
3279 Value *ShadowBase) {
3283 const size_t LargestStoreSizeInBytes =
3284 std::min<size_t>(
sizeof(uint64_t), ASan.LongSize / 8);
3286 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3292 for (
size_t i = Begin; i < End;) {
3293 if (!ShadowMask[i]) {
3299 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3301 while (StoreSizeInBytes > End - i)
3302 StoreSizeInBytes /= 2;
3305 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3306 while (j <= StoreSizeInBytes / 2)
3307 StoreSizeInBytes /= 2;
3311 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3313 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
3315 Val = (Val << 8) | ShadowBytes[i + j];
3318 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3324 i += StoreSizeInBytes;
3331 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3336 size_t Begin,
size_t End,
3339 size_t Done = Begin;
3340 for (
size_t i = Begin, j = Begin + 1; i < End; i =
j++) {
3341 if (!ShadowMask[i]) {
3345 uint8_t Val = ShadowBytes[i];
3346 if (!AsanSetShadowFunc[Val])
3350 for (;
j < End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3353 if (j - i >= ASan.MaxInlinePoisoningSize) {
3354 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3355 RTCI.createRuntimeCall(
3356 IRB, AsanSetShadowFunc[Val],
3357 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3358 ConstantInt::get(IntptrTy, j - i)});
3363 copyToShadowInline(ShadowMask, ShadowBytes,
Done, End, IRB, ShadowBase);
3371 for (
int i = 0;; i++, MaxSize *= 2)
3372 if (LocalStackSize <= MaxSize)
return i;
3376void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3378 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3386 if (Arg.hasByValAttr()) {
3387 Type *Ty = Arg.getParamByValType();
3388 const Align Alignment =
3389 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3393 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3396 Arg.replaceAllUsesWith(AI);
3398 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3399 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3407 Value *ValueIfFalse) {
3410 PHI->addIncoming(ValueIfFalse, CondBlock);
3412 PHI->addIncoming(ValueIfTrue, ThenBlock);
3416Value *FunctionStackPoisoner::createAllocaForLayout(
3425 nullptr,
"MyAlloca");
3429 uint64_t FrameAlignment = std::max(
L.FrameAlignment, uint64_t(
ClRealignStack));
3434void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3437 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3442void FunctionStackPoisoner::processDynamicAllocas() {
3449 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3452 assert(ASan.isInterestingAlloca(*APC.AI));
3453 assert(!APC.AI->isStaticAlloca());
3456 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3463 createDynamicAllocasInitStorage();
3464 for (
auto &AI : DynamicAllocaVec)
3465 handleDynamicAllocaCall(AI);
3466 unpoisonDynamicAllocas();
3478 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3495 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3498 Value *Val = Store->getValueOperand();
3500 bool IsArgInitViaCast =
3505 Val == It->getPrevNode();
3506 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3510 if (IsArgInitViaCast)
3525 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3528 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3532 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3535 auto MetadataString =
3537 if (MetadataString->getString() ==
"alloca_name_altered")
3546void FunctionStackPoisoner::processStaticAllocas() {
3547 if (AllocaVec.
empty()) {
3552 int StackMallocIdx = -1;
3554 if (
auto SP =
F.getSubprogram())
3555 EntryDebugLocation =
3564 auto InsBeforeB = InsBefore->
getParent();
3565 assert(InsBeforeB == &
F.getEntryBlock());
3566 for (
auto *AI : StaticAllocasToMoveUp)
3577 ArgInitInst->moveBefore(InsBefore->
getIterator());
3580 if (LocalEscapeCall)
3588 ASan.getAllocaSizeInBytes(*AI),
3599 uint64_t Granularity = 1ULL << Mapping.Scale;
3600 uint64_t MinHeaderSize = std::max((uint64_t)ASan.LongSize / 2, Granularity);
3606 for (
auto &
Desc : SVD)
3610 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3613 assert(ASan.isInterestingAlloca(*APC.AI));
3614 assert(APC.AI->isStaticAlloca());
3619 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3620 if (LifetimeLoc->getFile() == FnLoc->getFile())
3621 if (
unsigned Line = LifetimeLoc->getLine())
3622 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3628 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3629 uint64_t LocalStackSize =
L.FrameSize;
3630 bool DoStackMalloc =
3640 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3641 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3643 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3644 Value *StaticAlloca =
3645 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3647 Value *FakeStackPtr;
3648 Value *FakeStackInt;
3649 Value *LocalStackBase;
3650 Value *LocalStackBaseAlloca;
3653 if (DoStackMalloc) {
3654 LocalStackBaseAlloca =
3655 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3662 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3672 Value *FakeStackValue =
3673 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3674 ConstantInt::get(IntptrTy, LocalStackSize));
3676 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3677 Term, ConstantInt::get(IntptrTy, 0));
3685 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3686 ConstantInt::get(IntptrTy, LocalStackSize));
3689 Value *NoFakeStack =
3694 Value *AllocaValue =
3695 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3699 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3700 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3708 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3709 LocalStackBaseAlloca = LocalStackBase;
3714 for (
const auto &
Desc : SVD) {
3718 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3729 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3737 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3744 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3747 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3749 if (!StaticAllocaPoisonCallVec.empty()) {
3753 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3756 size_t Begin =
Desc.Offset /
L.Granularity;
3757 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3760 copyToShadow(ShadowAfterScope,
3761 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3767 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3770 if (
I->isLifetimeStartOrEnd())
3771 I->eraseFromParent();
3784 if (DoStackMalloc) {
3785 assert(StackMallocIdx >= 0);
3802 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3804 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3806 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3808 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3810 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3811 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3812 IRBPoison.CreateStore(
3814 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3817 RTCI.createRuntimeCall(
3818 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3819 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3823 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3825 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3830 for (
auto *AI : AllocaVec)
3834void FunctionStackPoisoner::poisonAlloca(
Value *V, uint64_t
Size,
3838 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3839 RTCI.createRuntimeCall(
3840 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3841 {AddrArg, SizeArg});
3852void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3860 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3894 ConstantInt::get(IntptrTy, Alignment.
value()));
3897 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3908 if (
I->isLifetimeStartOrEnd())
3909 I->eraseFromParent();
3941 Size - uint64_t(
Offset) >= TypeStoreSize / 8;
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"))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void findStoresToUninstrumentedArgAllocas(AddressSanitizer &ASan, Instruction &InsBefore, SmallVectorImpl< Instruction * > &InitInsts)
Collect instructions in the entry block after InsBefore which initialize permanent storage for a func...
static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I, Instruction *InsertBefore, Value *Addr, MaybeAlign Alignment, unsigned Granularity, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp, RuntimeCallInserter &RTCI)
static const uint64_t kDefaultShadowScale
const char kAMDGPUUnreachableName[]
constexpr size_t kAccessSizeIndexMask
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClUsePrivateAlias("asan-use-private-alias", cl::desc("Use private aliases for global variables"), cl::Hidden, cl::init(true))
static const uint64_t kPS_ShadowOffset64
static const uint64_t kFreeBSD_ShadowOffset32
constexpr size_t kIsWriteShift
static const uint64_t kSmallX86_64ShadowOffsetAlignMask
static bool isInterestingPointerSubtraction(Instruction *I)
const char kAMDGPUAddressSharedName[]
const char kAsanStackFreeNameTemplate[]
constexpr size_t kCompileKernelMask
static cl::opt< bool > ClForceDynamicShadow("asan-force-dynamic-shadow", cl::desc("Load shadow address into a local variable for each function"), cl::Hidden, cl::init(false))
const char kAsanOptionDetectUseAfterReturn[]
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static const uint64_t kRISCV64_ShadowOffset64
static cl::opt< bool > ClInsertVersionCheck("asan-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
const char kAsanSetShadowPrefix[]
static cl::opt< AsanDtorKind > ClOverrideDestructorKind("asan-destructor-kind", cl::desc("Sets the ASan destructor kind. The default is to use the value " "provided to the pass constructor"), cl::values(clEnumValN(AsanDtorKind::None, "none", "No destructors"), clEnumValN(AsanDtorKind::Global, "global", "Use global destructors")), cl::init(AsanDtorKind::Invalid), cl::Hidden)
static Twine genName(StringRef suffix)
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static uint64_t GetCtorAndDtorPriority(Triple &TargetTriple)
const char kAsanStackMallocNameTemplate[]
static cl::opt< bool > ClInstrumentByval("asan-instrument-byval", cl::desc("instrument byval call arguments"), cl::Hidden, cl::init(true))
const char kAsanInitName[]
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClRedzoneByvalArgs("asan-redzone-byval-args", cl::desc("Create redzones for byval " "arguments (extra copy " "required)"), cl::Hidden, cl::init(true))
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
static cl::opt< bool > ClOptimizeCallbacks("asan-optimize-callbacks", cl::desc("Optimize callbacks"), cl::Hidden, cl::init(false))
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(true))
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static cl::opt< int > ClShadowAddrSpace("asan-shadow-addr-space", cl::desc("Address space for pointers to the shadow map"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClInvalidPointerCmp("asan-detect-invalid-pointer-cmp", cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInvalidPointerSub("asan-detect-invalid-pointer-sub", cl::desc("Instrument - operations with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static cl::list< unsigned > ClAddrSpaces("asan-instrument-address-spaces", cl::desc("Only instrument variables in the specified address spaces."), cl::Hidden, cl::CommaSeparated, cl::callback([](const unsigned &AddrSpace) { SrcAddrSpaces.insert(AddrSpace);}))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
constexpr size_t kAccessSizeIndexShift
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
const char kAsanPoisonStackMemoryName[]
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isSupportedAddrspace(const Triple &TargetTriple, Value *Addr)
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static cl::opt< AsanDetectStackUseAfterReturnMode > ClUseAfterReturn("asan-use-after-return", cl::desc("Sets the mode of detection for stack-use-after-return."), cl::values(clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", "Never detect stack use after return."), clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, "runtime", "Detect stack use after return if " "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", "Always detect stack use after return.")), cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime))
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static const uintptr_t kCurrentStackFrameMagic
static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kPPC64_ShadowOffset64
static cl::opt< AsanCtorKind > ClConstructorKind("asan-constructor-kind", cl::desc("Sets the ASan constructor kind"), cl::values(clEnumValN(AsanCtorKind::None, "none", "No constructors"), clEnumValN(AsanCtorKind::Global, "global", "Use global constructors")), cl::init(AsanCtorKind::Global), cl::Hidden)
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
static const uint64_t kNetBSD_ShadowOffset64
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
static const uint64_t kWindowsShadowOffset32
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
static SmallSet< unsigned, 8 > SrcAddrSpaces
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const char kAsanReportErrorTemplate[]
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
static StringRef getAllocaName(AllocaInst *AI)
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
static const uintptr_t kRetiredStackFrameMagic
static cl::opt< bool > ClUseStackSafety("asan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"), cl::Optional)
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
static cl::opt< int > ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
static cl::opt< bool > ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, cl::init(false))
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool isPointerOperand(Value *I, User *U)
static const Function * getParent(const Value *V)
static GCRegistry::Add< 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...
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.
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)
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign extended value.
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.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
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.
iterator begin()
Instruction iterator methods.
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.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
bool isInlineAsm() const
Check if this call is an inline asm statement.
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.
@ SameSize
The data referenced by the COMDAT must be the same size.
@ Any
The linker may choose any COMDAT.
@ NoDeduplicate
No deduplication is performed.
@ ExactMatch
The data referenced by the COMDAT must be the same.
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
ConstantArray - Constant Array Declarations.
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.
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...
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
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
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.
bool hasPersonalityFn() const
Check whether this function has a personality function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
const Constant * getAliasee() const
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...
LLVM_ABI void copyMetadata(const GlobalObject *Src, unsigned Offset)
Copy metadata from Src, adjusting offsets by Offset.
LLVM_ABI void setComdat(Comdat *C)
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
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.
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
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...
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.
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
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...
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
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.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
BasicBlock * GetInsertBlock() const
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
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="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
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.
Base class for instruction visitors.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
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.
ArrayRef< MDOperand > operands() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This is the common base class for memset/memcpy/memmove.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
static MemoryEffectsBase otherMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
A Module instance is used to store all the information related to an LLVM module.
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'.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Return a value (possibly void), from a function.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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 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).
bool stackAccessIsSafe(const Instruction &I) const
bool isSafe(const AllocaInst &AI) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
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.
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
Triple - Helper class for working with autoconf configuration names.
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
bool isDriverKit() const
Is this an Apple DriverKit triple.
bool isBPF() const
Tests whether the target is eBPF.
bool isAndroid() const
Tests whether the target is Android.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isOSWindows() const
Tests whether the OS is Windows.
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isOSLinux() const
Tests whether the OS is Linux.
bool isMacOSX() const
Is this a Mac OS X triple.
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
bool isWatchOS() const
Is this an Apple watchOS triple.
bool isiOS() const
Is this an iOS triple.
bool isPS() const
Tests whether the target is the PS4 or PS5 platform.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
bool isOSHaiku() const
Tests whether the OS is Haiku.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
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
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
cb< typename detail::callback_traits< F >::result_type, typename detail::callback_traits< F >::arg_type > callback(F CB)
uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
Context & getContext() const
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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.
FunctionAddr VTableAddr Value
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
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...
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...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
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)
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.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
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.
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.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
OperandBundleDefT< Value * > OperandBundleDef
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)
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)
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.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
AsanCtorKind
Types of ASan module constructors supported.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
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.
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.
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.
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.
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.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Information about a load/store intrinsic defined by the target.
SmallVector< InterestingMemoryOperand, 1 > InterestingOperands
A CRTP mix-in to automatically provide informational APIs needed for passes.
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.