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)
621 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
622 !IsRISCV64 && !IsLoongArch64 &&
623 !(Mapping.Offset & (Mapping.Offset - 1)) &&
625 Mapping.InGlobal =
ClWithIfunc && IsAndroid && IsArmOrThumb;
631 bool IsKasan, uint64_t *ShadowBase,
632 int *MappingScale,
bool *OrShadowOffset) {
634 *ShadowBase = Mapping.Offset;
635 *MappingScale = Mapping.Scale;
636 *OrShadowOffset = Mapping.OrShadowOffset;
657 if (!
F.getMemoryEffects()
659 .doesNotAccessMemory() &&
661 F.setMemoryEffects(
F.getMemoryEffects() |
669 F.setMemoryEffects(
F.getMemoryEffects() |
674 if (
A.hasAttribute(Attribute::WriteOnly)) {
675 A.removeAttr(Attribute::WriteOnly);
683 F.addFnAttr(Attribute::NoBuiltin);
704 return std::max(32U, 1U << MappingScale);
720class AsanFunctionInserter {
722 AsanFunctionInserter(
Module &M) :
M(
M) {}
724 template <
typename... ArgTypes>
725 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
726 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
739class RuntimeCallInserter {
741 bool TrackInsertedCalls =
false;
745 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
747 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
748 if (isScopedEHPersonality(Personality))
749 TrackInsertedCalls = true;
753 ~RuntimeCallInserter() {
754 if (InsertedCalls.
empty())
756 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
758 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
759 for (CallInst *CI : InsertedCalls) {
761 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
763 "Instruction doesn't belong to the expected Function!");
771 if (Colors.
size() != 1) {
773 "Instruction's BasicBlock is not monochromatic");
780 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
784 OB, CI->getIterator());
785 NewCall->copyMetadata(*CI);
786 CI->replaceAllUsesWith(NewCall);
787 CI->eraseFromParent();
792 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
794 const Twine &
Name =
"") {
797 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
798 if (TrackInsertedCalls)
799 InsertedCalls.push_back(Inst);
805struct AddressSanitizer {
806 AddressSanitizer(
Module &M,
const StackSafetyGlobalInfo *SSGI,
807 int InstrumentationWithCallsThreshold,
808 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
809 bool Recover =
false,
bool UseAfterScope =
false,
811 AsanDetectStackUseAfterReturnMode::Runtime)
820 InstrumentationWithCallsThreshold(
823 : InstrumentationWithCallsThreshold),
826 : MaxInlinePoisoningSize) {
827 C = &(
M.getContext());
828 DL = &
M.getDataLayout();
829 LongSize =
M.getDataLayout().getPointerSizeInBits();
830 IntptrTy = Type::getIntNTy(*
C, LongSize);
831 PtrTy = PointerType::getUnqual(*
C);
832 Int32Ty = Type::getInt32Ty(*
C);
833 TargetTriple =
M.getTargetTriple();
837 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
845 bool isInterestingAlloca(
const AllocaInst &AI);
847 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
849 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
850 const TargetTransformInfo *
TTI);
852 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
853 InterestingMemoryOperand &O,
bool UseCalls,
854 const DataLayout &
DL, RuntimeCallInserter &RTCI);
855 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
856 RuntimeCallInserter &RTCI);
858 Value *Addr, MaybeAlign Alignment,
859 uint32_t TypeStoreSize,
bool IsWrite,
860 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
861 RuntimeCallInserter &RTCI);
862 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
863 Instruction *InsertBefore,
Value *Addr,
864 uint32_t TypeStoreSize,
bool IsWrite,
865 Value *SizeArgument);
868 void instrumentUnusualSizeOrAlignment(Instruction *
I,
869 Instruction *InsertBefore,
Value *Addr,
870 TypeSize TypeStoreSize,
bool IsWrite,
871 Value *SizeArgument,
bool UseCalls,
873 RuntimeCallInserter &RTCI);
874 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
877 MaybeAlign Alignment,
unsigned Granularity,
878 Type *OpType,
bool IsWrite,
879 Value *SizeArgument,
bool UseCalls,
880 uint32_t Exp, RuntimeCallInserter &RTCI);
882 Value *ShadowValue, uint32_t TypeStoreSize);
884 bool IsWrite,
size_t AccessSizeIndex,
885 Value *SizeArgument, uint32_t Exp,
886 RuntimeCallInserter &RTCI);
887 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
889 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
890 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
891 const TargetTransformInfo *
TTI);
892 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
893 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
894 void markEscapedLocalAllocas(
Function &
F);
895 void markCatchParametersAsUninteresting(
Function &
F);
898 friend struct FunctionStackPoisoner;
900 void initializeCallbacks(
const TargetLibraryInfo *TLI);
902 bool LooksLikeCodeInBug11395(Instruction *
I);
903 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
904 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
905 TypeSize TypeStoreSize)
const;
908 struct FunctionStateRAII {
909 AddressSanitizer *
Pass;
911 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
913 "last pass forgot to clear cache");
917 ~FunctionStateRAII() {
918 Pass->LocalDynamicShadow =
nullptr;
919 Pass->ProcessedAllocas.clear();
924 AsanFunctionInserter Inserter;
926 const DataLayout *
DL;
936 ShadowMapping Mapping;
937 FunctionCallee AsanHandleNoReturnFunc;
938 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
946 FunctionCallee AsanErrorCallbackSized[2][2];
947 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
949 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
950 Value *LocalDynamicShadow =
nullptr;
951 const StackSafetyGlobalInfo *SSGI;
952 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
954 FunctionCallee AMDGPUAddressShared;
955 FunctionCallee AMDGPUAddressPrivate;
956 int InstrumentationWithCallsThreshold;
957 uint32_t MaxInlinePoisoningSize;
960class ModuleAddressSanitizer {
962 ModuleAddressSanitizer(
Module &M,
bool InsertVersionCheck,
963 bool CompileKernel =
false,
bool Recover =
false,
964 bool UseGlobalsGC =
true,
bool UseOdrIndicator =
true,
972 : InsertVersionCheck),
974 UseGlobalsGC(UseGlobalsGC &&
ClUseGlobalsGC && !this->CompileKernel),
989 UseCtorComdat(UseGlobalsGC &&
ClWithComdat && !this->CompileKernel),
990 DestructorKind(DestructorKind),
994 C = &(
M.getContext());
995 int LongSize =
M.getDataLayout().getPointerSizeInBits();
996 IntptrTy = Type::getIntNTy(*
C, LongSize);
997 PtrTy = PointerType::getUnqual(*
C);
998 TargetTriple =
M.getTargetTriple();
1003 assert(this->DestructorKind != AsanDtorKind::Invalid);
1006 bool instrumentModule();
1009 void initializeCallbacks();
1011 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
1018 const std::string &UniqueModuleId);
1023 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
1027 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
1028 StringRef OriginalName);
1029 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
1030 StringRef InternalSuffix);
1033 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
1034 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
1035 bool ShouldUseMachOGlobalsSection()
const;
1036 StringRef getGlobalMetadataSection()
const;
1037 void poisonOneInitializer(
Function &GlobalInit);
1038 void createInitializerPoisonCalls();
1039 uint64_t getMinRedzoneSizeForGlobal()
const {
1043 int GetAsanVersion()
const;
1044 GlobalVariable *getOrCreateModuleName();
1047 AsanFunctionInserter Inserter;
1049 bool InsertVersionCheck;
1052 bool UsePrivateAlias;
1053 bool UseOdrIndicator;
1060 Triple TargetTriple;
1061 ShadowMapping Mapping;
1062 FunctionCallee AsanPoisonGlobals;
1063 FunctionCallee AsanUnpoisonGlobals;
1064 FunctionCallee AsanRegisterGlobals;
1065 FunctionCallee AsanUnregisterGlobals;
1066 FunctionCallee AsanRegisterImageGlobals;
1067 FunctionCallee AsanUnregisterImageGlobals;
1068 FunctionCallee AsanRegisterElfGlobals;
1069 FunctionCallee AsanUnregisterElfGlobals;
1071 Function *AsanCtorFunction =
nullptr;
1072 Function *AsanDtorFunction =
nullptr;
1073 GlobalVariable *ModuleName =
nullptr;
1085struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
1087 AddressSanitizer &ASan;
1088 RuntimeCallInserter &RTCI;
1093 ShadowMapping Mapping;
1097 SmallVector<Instruction *, 8> RetVec;
1101 FunctionCallee AsanSetShadowFunc[0x100] = {};
1102 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
1103 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
1106 struct AllocaPoisonCall {
1107 IntrinsicInst *InsBefore;
1117 AllocaInst *DynamicAllocaLayout =
nullptr;
1118 IntrinsicInst *LocalEscapeCall =
nullptr;
1120 bool HasInlineAsm =
false;
1121 bool HasReturnsTwiceCall =
false;
1124 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
1125 RuntimeCallInserter &RTCI)
1126 :
F(
F), ASan(ASan), RTCI(RTCI),
1128 IntptrTy(ASan.IntptrTy),
1130 Mapping(ASan.Mapping),
1138 copyArgsPassedByValToAllocas();
1143 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
1145 initializeCallbacks(*
F.getParent());
1147 processDynamicAllocas();
1148 processStaticAllocas();
1159 void copyArgsPassedByValToAllocas();
1164 void processStaticAllocas();
1165 void processDynamicAllocas();
1167 void createDynamicAllocasInitStorage();
1172 void visitReturnInst(ReturnInst &RI) {
1173 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
1180 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
1183 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
1185 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
1186 Value *SavedStack) {
1195 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
1201 RTCI.createRuntimeCall(
1202 IRB, AsanAllocasUnpoisonFunc,
1203 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
1207 void unpoisonDynamicAllocas() {
1208 for (Instruction *Ret : RetVec)
1209 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
1211 for (Instruction *StackRestoreInst : StackRestoreVec)
1212 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
1213 StackRestoreInst->getOperand(0));
1226 void handleDynamicAllocaCall(AllocaInst *AI);
1229 void visitAllocaInst(AllocaInst &AI) {
1231 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
1235 if (AllocaVec.
empty())
1251 void visitIntrinsicInst(IntrinsicInst &
II) {
1253 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
1254 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
1255 if (!ASan.UseAfterScope)
1257 if (!
II.isLifetimeStartOrEnd())
1262 if (!AI || !ASan.isInterestingAlloca(*AI))
1272 bool DoPoison = (
ID == Intrinsic::lifetime_end);
1273 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
1275 StaticAllocaPoisonCallVec.
push_back(APC);
1277 DynamicAllocaPoisonCallVec.
push_back(APC);
1280 void visitCallBase(CallBase &CB) {
1282 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1283 HasReturnsTwiceCall |= CI->canReturnTwice();
1288 void initializeCallbacks(
Module &M);
1293 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1295 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1298 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1299 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1304 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1307 Instruction *ThenTerm,
Value *ValueIfFalse);
1314 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1315 OS, MapClassName2PassName);
1317 if (Options.CompileKernel)
1319 if (Options.UseAfterScope)
1320 OS <<
"use-after-scope";
1328 : Options(Options), UseGlobalGC(UseGlobalGC),
1329 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1330 ConstructorKind(ConstructorKind) {}
1339 ModuleAddressSanitizer ModuleSanitizer(
1340 M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
1341 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
1353 if (
F.getName().starts_with(
"__asan_"))
1355 if (
F.isPresplitCoroutine())
1357 AddressSanitizer FunctionSanitizer(
1358 M, SSGI, Options.InstrumentationWithCallsThreshold,
1359 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1360 Options.UseAfterScope, Options.UseAfterReturn);
1363 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1365 Modified |= ModuleSanitizer.instrumentModule();
1386 if (
G->getName().starts_with(
"llvm.") ||
1388 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1390 G->getName().starts_with(
"__llvm_rtti_proxy"))
1406 if (AddrSpace == 3 || AddrSpace == 5)
1421 return AddrSpace == 0;
1425 if (TargetTriple.isOSDarwin() &&
1429 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1432 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1433 if (Mapping.Offset == 0)
return Shadow;
1436 if (LocalDynamicShadow)
1437 ShadowBase = LocalDynamicShadow;
1439 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1440 if (Mapping.OrShadowOffset)
1441 return IRB.
CreateOr(Shadow, ShadowBase);
1443 return IRB.
CreateAdd(Shadow, ShadowBase);
1448 RuntimeCallInserter &RTCI) {
1451 RTCI.createRuntimeCall(
1457 RTCI.createRuntimeCall(
1463 MI->eraseFromParent();
1467bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1468 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1471 return It->getSecond();
1473 bool IsInteresting =
1484 !(SSGI && SSGI->
isSafe(AI)));
1486 It->second = IsInteresting;
1487 return IsInteresting;
1517void AddressSanitizer::getInterestingMemoryOperands(
1521 if (LocalDynamicShadow ==
I)
1527 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1528 LI->getType(), LI->getAlign());
1533 SI->getValueOperand()->getType(),
SI->getAlign());
1537 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1538 RMW->getValOperand()->getType(), std::nullopt);
1542 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1543 XCHG->getCompareOperand()->getType(),
1546 switch (CI->getIntrinsicID()) {
1547 case Intrinsic::masked_load:
1548 case Intrinsic::masked_store:
1549 case Intrinsic::masked_gather:
1550 case Intrinsic::masked_scatter: {
1551 bool IsWrite = CI->getType()->isVoidTy();
1553 unsigned OpOffset = IsWrite ? 1 : 0;
1557 auto BasePtr = CI->getOperand(OpOffset);
1558 if (ignoreAccess(
I, BasePtr))
1560 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1562 Value *
Mask = CI->getOperand(1 + OpOffset);
1563 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1566 case Intrinsic::masked_expandload:
1567 case Intrinsic::masked_compressstore: {
1568 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1569 unsigned OpOffset = IsWrite ? 1 : 0;
1572 auto BasePtr = CI->getOperand(OpOffset);
1573 if (ignoreAccess(
I, BasePtr))
1576 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1579 Value *
Mask = CI->getOperand(1 + OpOffset);
1582 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1583 Value *EVL =
IB.CreateAddReduce(ExtMask);
1584 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1585 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1589 case Intrinsic::vp_load:
1590 case Intrinsic::vp_store:
1591 case Intrinsic::experimental_vp_strided_load:
1592 case Intrinsic::experimental_vp_strided_store: {
1594 unsigned IID = CI->getIntrinsicID();
1595 bool IsWrite = CI->getType()->isVoidTy();
1598 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1599 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1601 Value *Stride =
nullptr;
1602 if (IID == Intrinsic::experimental_vp_strided_store ||
1603 IID == Intrinsic::experimental_vp_strided_load) {
1604 Stride = VPI->getOperand(PtrOpNo + 1);
1608 unsigned PointerAlign =
Alignment.valueOrOne().value();
1613 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1614 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1618 case Intrinsic::vp_gather:
1619 case Intrinsic::vp_scatter: {
1621 unsigned IID = CI->getIntrinsicID();
1622 bool IsWrite = IID == Intrinsic::vp_scatter;
1625 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1626 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1628 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1629 VPI->getMaskParam(),
1630 VPI->getVectorLengthParam());
1636 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1640 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1642 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1644 Type *Ty = CI->getParamByValType(ArgNo);
1660 if (!Cmp->isRelational())
1674 if (BO->getOpcode() != Instruction::Sub)
1687 if (!
G->hasInitializer())
1690 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1697 Type *Ty = V->getType();
1698 if (Ty->isPtrOrPtrVectorTy())
1704bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1706 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1721 "invalid vector pointer pair instrumentation operands");
1722 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1723 Index != NumElements; ++Index) {
1724 Value *ScalarParam[2] = {
1731 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1738 RTCI.createRuntimeCall(IRB,
F, Param);
1745 TypeSize TypeStoreSize,
bool IsWrite,
1746 Value *SizeArgument,
bool UseCalls,
1747 uint32_t Exp, RuntimeCallInserter &RTCI) {
1752 switch (FixedSize) {
1758 if (!Alignment || *Alignment >= Granularity ||
1759 *Alignment >= FixedSize / 8)
1760 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1761 FixedSize, IsWrite,
nullptr, UseCalls,
1765 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1766 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1769void AddressSanitizer::instrumentMaskedLoadOrStore(
1772 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1773 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1774 RuntimeCallInserter &RTCI) {
1776 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1777 auto Zero = ConstantInt::get(IntptrTy, 0);
1785 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1787 IB.SetInsertPoint(LoopInsertBefore);
1789 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1792 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1793 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1795 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1800 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1804 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1805 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1806 if (MaskElemC->isZero())
1812 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1813 MaskElem, &*IRB.GetInsertPoint(), false);
1814 IRB.SetInsertPoint(ThenTerm);
1817 Value *InstrumentedAddress;
1820 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1821 "Expected vector of pointer.");
1822 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1823 }
else if (Stride) {
1830 Alignment, Granularity, ElemTypeSize, IsWrite,
1831 SizeArgument, UseCalls, Exp, RTCI);
1838 RuntimeCallInserter &RTCI) {
1839 Value *Addr =
O.getPtr();
1859 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1860 NumOptimizedAccessesToGlobalVar++;
1868 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1869 NumOptimizedAccessesToStackVar++;
1875 NumInstrumentedWrites++;
1877 NumInstrumentedReads++;
1879 if (
O.MaybeByteOffset) {
1884 if (TargetTriple.isRISCV()) {
1889 static_cast<unsigned>(LongSize)) {
1898 unsigned Granularity = 1 << Mapping.Scale;
1900 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1901 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1902 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1903 UseCalls, Exp, RTCI);
1906 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1907 UseCalls, Exp, RTCI);
1912 Value *Addr,
bool IsWrite,
1913 size_t AccessSizeIndex,
1914 Value *SizeArgument,
1916 RuntimeCallInserter &RTCI) {
1922 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1923 {Addr, SizeArgument});
1925 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1926 {Addr, SizeArgument, ExpVal});
1929 Call = RTCI.createRuntimeCall(
1930 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1932 Call = RTCI.createRuntimeCall(
1933 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1942 uint32_t TypeStoreSize) {
1943 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1945 Value *LastAccessedByte =
1946 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1948 if (TypeStoreSize / 8 > 1)
1950 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1953 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1958Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1960 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1967 return InsertBefore;
1972 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1974 Value *AddrSpaceZeroLanding =
1977 return InsertBefore;
1992 Trm->getParent()->setName(
"asan.report");
2003void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
2006 uint32_t TypeStoreSize,
bool IsWrite,
2007 Value *SizeArgument,
bool UseCalls,
2009 RuntimeCallInserter &RTCI) {
2010 if (TargetTriple.isAMDGPU()) {
2011 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
2012 TypeStoreSize, IsWrite, SizeArgument);
2021 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
2024 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
2031 RTCI.createRuntimeCall(
2032 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
2034 RTCI.createRuntimeCall(
2035 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
2036 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
2043 Value *ShadowPtr = memToShadow(AddrLong, IRB);
2045 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
2050 size_t Granularity = 1ULL << Mapping.Scale;
2053 bool GenSlowPath = (
ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
2055 if (TargetTriple.isAMDGCN()) {
2057 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2060 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2061 }
else if (GenSlowPath) {
2068 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2083 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2092void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2094 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
2095 uint32_t Exp, RuntimeCallInserter &RTCI) {
2103 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2106 RTCI.createRuntimeCall(
2107 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2121void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
2127 Value *ModuleNameAddr =
2135 for (
auto &BB : GlobalInit)
2147void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2167 poisonOneInitializer(*
F);
2173ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
2178 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
2190bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
2191 Type *Ty =
G->getValueType();
2194 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
2196 if (!Ty->
isSized())
return false;
2197 if (!
G->hasInitializer())
return false;
2204 if (
G->isThreadLocal())
return false;
2206 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
2212 if (!TargetTriple.isOSBinFormatCOFF()) {
2213 if (!
G->hasExactDefinition() ||
G->hasComdat())
2217 if (
G->isInterposable())
2221 if (
G->hasAvailableExternallyLinkage())
2228 switch (
C->getSelectionKind()) {
2239 if (
G->hasSection()) {
2249 if (Section ==
"llvm.metadata")
return false;
2256 if (
Section.starts_with(
".preinit_array") ||
2257 Section.starts_with(
".init_array") ||
2258 Section.starts_with(
".fini_array")) {
2264 if (TargetTriple.isOSBinFormatELF()) {
2278 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2279 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2284 if (TargetTriple.isOSBinFormatMachO()) {
2286 unsigned TAA = 0, StubSize = 0;
2289 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2294 if (ParsedSegment ==
"__OBJC" ||
2295 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2307 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2320 if (CompileKernel) {
2323 if (
G->getName().starts_with(
"__"))
2333bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2334 if (!TargetTriple.isOSBinFormatMachO())
2337 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2339 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2341 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2343 if (TargetTriple.isDriverKit())
2345 if (TargetTriple.isXROS())
2351StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2352 switch (TargetTriple.getObjectFormat()) {
2362 "ModuleAddressSanitizer not implemented for object file format");
2369void ModuleAddressSanitizer::initializeCallbacks() {
2375 AsanUnpoisonGlobals =
2379 AsanRegisterGlobals = Inserter.insertFunction(
2381 AsanUnregisterGlobals = Inserter.insertFunction(
2386 AsanRegisterImageGlobals = Inserter.insertFunction(
2388 AsanUnregisterImageGlobals = Inserter.insertFunction(
2391 AsanRegisterElfGlobals =
2393 IntptrTy, IntptrTy, IntptrTy);
2394 AsanUnregisterElfGlobals =
2396 IntptrTy, IntptrTy, IntptrTy);
2401void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2406 if (!
G->hasName()) {
2410 G->setName(
genName(
"anon_global"));
2413 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2414 std::string
Name = std::string(
G->getName());
2415 Name += InternalSuffix;
2416 C =
M.getOrInsertComdat(Name);
2418 C =
M.getOrInsertComdat(
G->getName());
2424 if (TargetTriple.isOSBinFormatCOFF()) {
2426 if (
G->hasPrivateLinkage())
2439ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2441 auto Linkage = TargetTriple.isOSBinFormatMachO()
2447 Metadata->setSection(getGlobalMetadataSection());
2454Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2458 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2466void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2470 auto &
DL =
M.getDataLayout();
2473 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2474 Constant *Initializer = MetadataInitializers[i];
2478 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2484 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2486 "global metadata will not be padded appropriately");
2489 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2494 if (!MetadataGlobals.empty())
2498void ModuleAddressSanitizer::instrumentGlobalsELF(
2501 const std::string &UniqueModuleId) {
2508 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2511 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2514 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2516 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2519 if (UseComdatForGlobalsGC)
2520 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2525 if (!MetadataGlobals.empty())
2542 "__start_" + getGlobalMetadataSection());
2546 "__stop_" + getGlobalMetadataSection());
2560 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2567void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2578 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2579 Constant *Initializer = MetadataInitializers[i];
2585 auto LivenessBinder =
2590 Twine(
"__asan_binder_") +
G->getName());
2591 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2592 LivenessGlobals[i] = Liveness;
2599 if (!LivenessGlobals.empty())
2621 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2626void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2630 unsigned N = ExtendedGlobals.
size();
2640 if (Mapping.Scale > 3)
2641 AllGlobals->setAlignment(
Align(1ULL << Mapping.Scale));
2646 ConstantInt::get(IntptrTy,
N)});
2652 IrbDtor.CreateCall(AsanUnregisterGlobals,
2654 ConstantInt::get(IntptrTy,
N)});
2663void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2668 if (CompileKernel) {
2669 for (
auto &GA :
M.aliases()) {
2671 AliasedGlobalExclusions.
insert(GV);
2676 for (
auto &
G :
M.globals()) {
2677 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2681 size_t n = GlobalsToChange.
size();
2682 auto &
DL =
M.getDataLayout();
2696 IntptrTy, IntptrTy, IntptrTy);
2700 for (
size_t i = 0; i < n; i++) {
2704 if (
G->hasSanitizerMetadata())
2705 MD =
G->getSanitizerMetadata();
2710 std::string NameForGlobal =
G->getName().str();
2715 Type *Ty =
G->getValueType();
2716 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2729 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2730 G->getThreadLocalMode(),
G->getAddressSpace());
2740 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2743 if (Seq && Seq->isCString())
2744 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2751 G->replaceAllUsesWith(NewGlobal);
2753 G->eraseFromParent();
2754 NewGlobals[i] = NewGlobal;
2759 bool CanUsePrivateAliases =
2760 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2761 TargetTriple.isOSBinFormatWasm();
2762 if (CanUsePrivateAliases && UsePrivateAlias) {
2765 InstrumentedGlobal =
2772 }
else if (UseOdrIndicator) {
2775 auto *ODRIndicatorSym =
2784 ODRIndicatorSym->setAlignment(
Align(1));
2791 ConstantInt::get(IntptrTy, SizeInBytes),
2792 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2795 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2800 Initializers[i] = Initializer;
2806 for (
size_t i = 0; i < n; i++) {
2808 if (
G->getName().empty())
continue;
2813 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2820 }
else if (n == 0) {
2823 *CtorComdat = TargetTriple.isOSBinFormatELF();
2825 *CtorComdat =
false;
2826 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2827 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2828 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2829 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2831 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2837 createInitializerPoisonCalls();
2843ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2844 constexpr uint64_t kMaxRZ = 1 << 18;
2845 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2848 if (SizeInBytes <= MinRZ / 2) {
2852 RZ = MinRZ - SizeInBytes;
2855 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2858 if (SizeInBytes % MinRZ)
2859 RZ += MinRZ - (SizeInBytes % MinRZ);
2862 assert((RZ + SizeInBytes) % MinRZ == 0);
2867int ModuleAddressSanitizer::GetAsanVersion()
const {
2868 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2869 bool isAndroid =
M.getTargetTriple().isAndroid();
2873 Version += (LongSize == 32 && isAndroid);
2888bool ModuleAddressSanitizer::instrumentModule() {
2889 initializeCallbacks();
2897 if (CompileKernel) {
2902 std::string AsanVersion = std::to_string(GetAsanVersion());
2903 std::string VersionCheckName =
2905 std::tie(AsanCtorFunction, std::ignore) =
2908 {}, VersionCheckName);
2912 bool CtorComdat =
true;
2915 if (AsanCtorFunction) {
2916 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2917 instrumentGlobals(IRB, &CtorComdat);
2920 instrumentGlobals(IRB, &CtorComdat);
2929 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2930 if (AsanCtorFunction) {
2934 if (AsanDtorFunction) {
2939 if (AsanCtorFunction)
2941 if (AsanDtorFunction)
2952 for (
int Exp = 0;
Exp < 2;
Exp++) {
2953 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2954 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2955 const std::string ExpStr =
Exp ?
"exp_" :
"";
2956 const std::string EndingStr = Recover ?
"_noabort" :
"";
2966 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2967 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2968 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2971 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2975 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2976 Inserter.insertFunction(
2981 AccessSizeIndex++) {
2982 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2983 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2984 Inserter.insertFunction(
2988 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2989 Inserter.insertFunction(
2996 const std::string MemIntrinCallbackPrefix =
3000 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
3001 PtrTy, PtrTy, PtrTy, IntptrTy);
3002 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
3003 PtrTy, PtrTy, PtrTy, IntptrTy);
3005 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
3010 AsanHandleNoReturnFunc =
3013 AsanPtrCmpFunction =
3015 AsanPtrSubFunction =
3017 if (Mapping.InGlobal)
3018 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
3021 AMDGPUAddressShared =
3027bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
3035 if (
F.getName().contains(
" load]")) {
3045bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
3051 if (Mapping.InGlobal) {
3059 LocalDynamicShadow =
3060 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
3062 LocalDynamicShadow =
3066 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
3068 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
3073void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
3078 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
3082 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
3088 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
3090 for (
Value *Arg :
II->args()) {
3093 "non-static alloca arg to localescape");
3094 ProcessedAllocas[AI] =
false;
3103void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
3109 for (
Value *Operand : CatchPad->arg_operands())
3111 ProcessedAllocas[AI] =
false;
3117bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
3118 bool ShouldInstrument =
3122 return !ShouldInstrument;
3125bool AddressSanitizer::instrumentFunction(
Function &
F,
3128 bool FunctionModified =
false;
3131 if (
F.hasFnAttribute(Attribute::Naked))
3132 return FunctionModified;
3137 if (maybeInsertAsanInitAtFunctionEntry(
F))
3138 FunctionModified =
true;
3141 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
3143 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3144 return FunctionModified;
3148 initializeCallbacks(TLI);
3150 FunctionStateRAII CleanupObj(
this);
3152 RuntimeCallInserter RTCI(
F);
3154 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
3158 markEscapedLocalAllocas(
F);
3160 if (TargetTriple.isOSWindows())
3161 markCatchParametersAsUninteresting(
F);
3173 for (
auto &BB :
F) {
3175 TempsToInstrument.
clear();
3176 int NumInsnsPerBB = 0;
3177 for (
auto &Inst : BB) {
3178 if (LooksLikeCodeInBug11395(&Inst))
return false;
3185 if (!InterestingOperands.
empty()) {
3186 for (
auto &Operand : InterestingOperands) {
3188 Value *Ptr = Operand.getPtr();
3192 if (Operand.MaybeMask) {
3193 if (TempsToInstrument.
count(Ptr))
3196 if (!TempsToInstrument.
insert(Ptr).second)
3200 OperandsToInstrument.
push_back(Operand);
3207 PointerComparisonsOrSubtracts.
push_back(&Inst);
3215 TempsToInstrument.
clear();
3226 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3227 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
3228 (
unsigned)InstrumentationWithCallsThreshold);
3233 int NumInstrumented = 0;
3234 for (
auto &Operand : OperandsToInstrument) {
3235 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3236 instrumentMop(ObjSizeVis, Operand, UseCalls,
3237 F.getDataLayout(), RTCI);
3238 FunctionModified =
true;
3240 for (
auto *Inst : IntrinToInstrument) {
3241 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3242 instrumentMemIntrinsic(Inst, RTCI);
3243 FunctionModified =
true;
3246 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3247 bool ChangedStack = FSP.runOnFunction();
3251 for (
auto *CI : NoReturnCalls) {
3253 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3256 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3257 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3260 if (ChangedStack || !NoReturnCalls.empty())
3261 FunctionModified =
true;
3263 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3266 return FunctionModified;
3272bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3273 if (LongSize != 32)
return false;
3282void FunctionStackPoisoner::initializeCallbacks(
Module &) {
3286 const char *MallocNameTemplate =
3291 std::string Suffix =
itostr(Index);
3292 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3293 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3294 AsanStackFreeFunc[
Index] =
3299 if (ASan.UseAfterScope) {
3300 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3302 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3306 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3307 0xf3, 0xf5, 0xf8}) {
3308 std::ostringstream
Name;
3310 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3311 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3315 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3317 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3323 size_t Begin,
size_t End,
3325 Value *ShadowBase) {
3329 const size_t LargestStoreSizeInBytes =
3330 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3332 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3338 for (
size_t i = Begin; i < End;) {
3339 if (!ShadowMask[i]) {
3345 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3347 while (StoreSizeInBytes > End - i)
3348 StoreSizeInBytes /= 2;
3351 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3352 while (j <= StoreSizeInBytes / 2)
3353 StoreSizeInBytes /= 2;
3357 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3359 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3361 Val = (Val << 8) | ShadowBytes[i + j];
3364 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3370 i += StoreSizeInBytes;
3377 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3382 size_t Begin,
size_t End,
3385 size_t Done = Begin;
3386 for (
size_t i = Begin, j = Begin + 1; i < End; i =
j++) {
3387 if (!ShadowMask[i]) {
3391 uint8_t Val = ShadowBytes[i];
3392 if (!AsanSetShadowFunc[Val])
3396 for (;
j < End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3399 if (j - i >= ASan.MaxInlinePoisoningSize) {
3400 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3401 RTCI.createRuntimeCall(
3402 IRB, AsanSetShadowFunc[Val],
3403 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3404 ConstantInt::get(IntptrTy, j - i)});
3409 copyToShadowInline(ShadowMask, ShadowBytes,
Done, End, IRB, ShadowBase);
3417 for (
int i = 0;; i++, MaxSize *= 2)
3418 if (LocalStackSize <= MaxSize)
return i;
3422void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3424 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3432 if (Arg.hasByValAttr()) {
3433 Type *Ty = Arg.getParamByValType();
3435 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3439 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3442 Arg.replaceAllUsesWith(AI);
3444 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3445 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3453 Value *ValueIfFalse) {
3456 PHI->addIncoming(ValueIfFalse, CondBlock);
3458 PHI->addIncoming(ValueIfTrue, ThenBlock);
3462Value *FunctionStackPoisoner::createAllocaForLayout(
3471 nullptr,
"MyAlloca");
3480void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3483 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3488void FunctionStackPoisoner::processDynamicAllocas() {
3495 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3498 assert(ASan.isInterestingAlloca(*APC.AI));
3499 assert(!APC.AI->isStaticAlloca());
3502 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3509 createDynamicAllocasInitStorage();
3510 for (
auto &AI : DynamicAllocaVec)
3511 handleDynamicAllocaCall(AI);
3512 unpoisonDynamicAllocas();
3524 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3541 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3546 bool IsArgInitViaCast =
3551 Val == It->getPrevNode();
3552 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3556 if (IsArgInitViaCast)
3571 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3574 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3578 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3581 auto MetadataString =
3583 if (MetadataString->getString() ==
"alloca_name_altered")
3592void FunctionStackPoisoner::processStaticAllocas() {
3593 if (AllocaVec.
empty()) {
3598 int StackMallocIdx = -1;
3600 if (
auto SP =
F.getSubprogram())
3601 EntryDebugLocation =
3610 auto InsBeforeB = InsBefore->
getParent();
3611 assert(InsBeforeB == &
F.getEntryBlock());
3612 for (
auto *AI : StaticAllocasToMoveUp)
3623 ArgInitInst->moveBefore(InsBefore->
getIterator());
3626 if (LocalEscapeCall)
3634 ASan.getAllocaSizeInBytes(*AI),
3645 uint64_t Granularity = 1ULL << Mapping.Scale;
3646 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3652 for (
auto &
Desc : SVD)
3656 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3659 assert(ASan.isInterestingAlloca(*APC.AI));
3660 assert(APC.AI->isStaticAlloca());
3665 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3666 if (LifetimeLoc->getFile() == FnLoc->getFile())
3667 if (
unsigned Line = LifetimeLoc->getLine())
3668 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3674 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3676 bool DoStackMalloc =
3686 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3687 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3689 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3690 Value *StaticAlloca =
3691 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3693 Value *FakeStackPtr;
3694 Value *FakeStackInt;
3695 Value *LocalStackBase;
3696 Value *LocalStackBaseAlloca;
3699 if (DoStackMalloc) {
3700 LocalStackBaseAlloca =
3701 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3708 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3718 Value *FakeStackValue =
3719 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3720 ConstantInt::get(IntptrTy, LocalStackSize));
3722 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3723 Term, ConstantInt::get(IntptrTy, 0));
3731 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3732 ConstantInt::get(IntptrTy, LocalStackSize));
3735 Value *NoFakeStack =
3740 Value *AllocaValue =
3741 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3745 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3746 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3754 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3755 LocalStackBaseAlloca = LocalStackBase;
3760 for (
const auto &
Desc : SVD) {
3764 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3777 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3785 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3792 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3795 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3797 if (!StaticAllocaPoisonCallVec.empty()) {
3801 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3804 size_t Begin =
Desc.Offset /
L.Granularity;
3805 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3808 copyToShadow(ShadowAfterScope,
3809 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3815 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3818 if (
I->isLifetimeStartOrEnd())
3819 I->eraseFromParent();
3832 if (DoStackMalloc) {
3833 assert(StackMallocIdx >= 0);
3850 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3852 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3854 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3856 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3858 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3859 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3860 IRBPoison.CreateStore(
3862 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3865 RTCI.createRuntimeCall(
3866 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3867 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3871 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3873 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3878 for (
auto *AI : AllocaVec)
3886 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3887 RTCI.createRuntimeCall(
3888 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3889 {AddrArg, SizeArg});
3900void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3908 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3942 ConstantInt::get(IntptrTy,
Alignment.value()));
3945 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3956 if (
I->isLifetimeStartOrEnd())
3957 I->eraseFromParent();
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 bool isPointerPairOperand(Value *V, Type *IntptrTy)
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
static cl::opt< bool > ClOptimizeCallbacks("asan-optimize-callbacks", cl::desc("Optimize callbacks"), cl::Hidden, cl::init(false))
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(true))
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static cl::opt< int > ClShadowAddrSpace("asan-shadow-addr-space", cl::desc("Address space for pointers to the shadow map"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClInvalidPointerCmp("asan-detect-invalid-pointer-cmp", cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInvalidPointerSub("asan-detect-invalid-pointer-sub", cl::desc("Instrument - operations with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static cl::list< unsigned > ClAddrSpaces("asan-instrument-address-spaces", cl::desc("Only instrument variables in the specified address spaces."), cl::Hidden, cl::CommaSeparated, cl::callback([](const unsigned &AddrSpace) { SrcAddrSpaces.insert(AddrSpace);}))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
constexpr size_t kAccessSizeIndexShift
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
const char kAsanPoisonStackMemoryName[]
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isSupportedAddrspace(const Triple &TargetTriple, Value *Addr)
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static cl::opt< AsanDetectStackUseAfterReturnMode > ClUseAfterReturn("asan-use-after-return", cl::desc("Sets the mode of detection for stack-use-after-return."), cl::values(clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", "Never detect stack use after return."), clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, "runtime", "Detect stack use after return if " "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", "Always detect stack use after return.")), cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime))
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static const uintptr_t kCurrentStackFrameMagic
static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kPPC64_ShadowOffset64
static cl::opt< AsanCtorKind > ClConstructorKind("asan-constructor-kind", cl::desc("Sets the ASan constructor kind"), cl::values(clEnumValN(AsanCtorKind::None, "none", "No constructors"), clEnumValN(AsanCtorKind::Global, "global", "Use global constructors")), cl::init(AsanCtorKind::Global), cl::Hidden)
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
static const uint64_t kNetBSD_ShadowOffset64
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
static const uint64_t kWindowsShadowOffset32
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
static SmallSet< unsigned, 8 > SrcAddrSpaces
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const char kAsanReportErrorTemplate[]
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
static StringRef getAllocaName(AllocaInst *AI)
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
static const uintptr_t kRetiredStackFrameMagic
static cl::opt< bool > ClUseStackSafety("asan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"), cl::Optional)
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
static cl::opt< int > ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
static cl::opt< bool > ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, cl::init(false))
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool isPointerOperand(Value *I, User *U)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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.
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...
LLVM_ABI DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
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
DISubprogram * getSubprogram() const
Get the attached subprogram.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
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.
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNull=false)
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...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
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="")
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())
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
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="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
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 * 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.
iterator_range< user_iterator > users()
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
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).
LLVM_ABI bool stackAccessIsSafe(const Instruction &I) const
LLVM_ABI bool isSafe(const AllocaInst &AI) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
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
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized() const
Return true if it makes sense to take the size of this type.
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'.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element 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.
@ 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)
LLVM_ABI uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
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.
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.
LLVM_ABI Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
AsanDetectStackUseAfterReturnMode
Mode of ASan detect stack use after return.
@ Always
Always detect stack use after return.
@ Never
Never detect stack use after return.
@ Runtime
Detect stack use after return if not disabled runtime with (ASAN_OPTIONS=detect_stack_use_after_retur...
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
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...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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)
LLVM_ABI void removeASanIncompatibleFnAttributes(Function &F, bool ReadsArgMem)
Remove memory attributes that are incompatible with the instrumentation added by AddressSanitizer and...
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isModAndRefSet(const ModRefInfo MRI)
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 ...
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.
LLVM_ABI void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
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.
Information about a load/store intrinsic defined by the target.
SmallVector< InterestingMemoryOperand, 1 > InterestingOperands
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.