97#define DEBUG_TYPE "asan"
103 std::numeric_limits<uint64_t>::max();
144 "__asan_unregister_image_globals";
157 "__asan_stack_malloc_always_";
171 "__asan_option_detect_stack_use_after_return";
174 "__asan_shadow_memory_dynamic_address";
200 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
205 cl::desc(
"Enable recovery mode (continue-after-error)."),
209 "asan-guard-against-version-mismatch",
215 cl::desc(
"instrument read instructions"),
219 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
228 "asan-instrument-atomics",
238 "asan-always-slow-path",
243 "asan-force-dynamic-shadow",
244 cl::desc(
"Load shadow address into a local variable for each function"),
249 cl::desc(
"Access dynamic shadow through an ifunc global on "
250 "platforms that support this"),
255 cl::desc(
"Address space for pointers to the shadow map"),
259 "asan-with-ifunc-suppress-remat",
260 cl::desc(
"Suppress rematerialization of dynamic shadow address by passing "
261 "it through inline asm in prologue."),
269 "asan-max-ins-per-bb",
cl::init(10000),
270 cl::desc(
"maximal number of instructions to instrument in any given BB"),
277 "asan-max-inline-poisoning-size",
279 "Inline shadow poisoning for blocks up to the given size in bytes."),
283 "asan-use-after-return",
284 cl::desc(
"Sets the mode of detection for stack-use-after-return."),
287 "Never detect stack use after return."),
290 "Detect stack use after return if "
291 "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."),
293 "Always detect stack use after return.")),
297 cl::desc(
"Create redzones for byval "
298 "arguments (extra copy "
303 cl::desc(
"Check stack-use-after-scope"),
312 cl::desc(
"Handle C++ initializer order"),
316 "asan-detect-invalid-pointer-pair",
321 "asan-detect-invalid-pointer-cmp",
326 "asan-detect-invalid-pointer-sub",
331 "asan-realign-stack",
332 cl::desc(
"Realign stack to the value of this flag (power of two)"),
336 "asan-instrumentation-with-call-threshold",
337 cl::desc(
"If the function being instrumented contains more than "
338 "this number of memory accesses, use callbacks instead of "
339 "inline checks (-1 means never use callbacks)."),
343 "asan-memory-access-callback-prefix",
348 "asan-kernel-mem-intrinsic-prefix",
354 cl::desc(
"instrument dynamic allocas"),
358 "asan-skip-promotable-allocas",
363 "asan-constructor-kind",
364 cl::desc(
"Sets the ASan constructor kind"),
367 "Use global constructors")),
374 cl::desc(
"scale of asan shadow mapping"),
379 cl::desc(
"offset of asan shadow mapping [EXPERIMENTAL]"),
393 "asan-opt-same-temp",
cl::desc(
"Instrument the same temp just once"),
397 cl::desc(
"Don't instrument scalar globals"),
401 "asan-opt-stack",
cl::desc(
"Don't instrument scalar stack variables"),
405 "asan-stack-dynamic-alloca",
410 "asan-force-experiment",
416 cl::desc(
"Use private aliases for global variables"),
421 cl::desc(
"Use odr indicators to improve ODR reporting"),
426 cl::desc(
"Use linker features to support dead "
427 "code stripping of globals"),
434 cl::desc(
"Place ASan constructors in comdat sections"),
438 "asan-destructor-kind",
439 cl::desc(
"Sets the ASan destructor kind. The default is to use the value "
440 "provided to the pass constructor"),
443 "Use global destructors")),
448 "asan-instrument-address-spaces",
449 cl::desc(
"Only instrument variables in the specified address spaces."),
471STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
472STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
474 "Number of optimized accesses to global vars");
476 "Number of optimized accesses to stack vars");
485struct ShadowMapping {
496 bool IsAndroid = TargetTriple.
isAndroid();
499 bool IsMacOS = TargetTriple.
isMacOSX();
502 bool IsPS = TargetTriple.
isPS();
508 bool IsMIPSN32ABI = TargetTriple.
isABIN32();
509 bool IsMIPS32 = TargetTriple.
isMIPS32();
510 bool IsMIPS64 = TargetTriple.
isMIPS64();
511 bool IsArmOrThumb = TargetTriple.
isARM() || TargetTriple.
isThumb();
518 bool IsAMDGPU = TargetTriple.
isAMDGPU();
520 bool IsWasm = TargetTriple.
isWasm();
521 bool IsBPF = TargetTriple.
isBPF();
523 ShadowMapping Mapping;
530 if (LongSize == 32) {
533 else if (IsMIPSN32ABI)
559 else if (IsFreeBSD && IsAArch64)
561 else if (IsFreeBSD && !IsMIPS64) {
566 }
else if (IsNetBSD) {
573 else if (IsLinux && IsX86_64) {
579 }
else if (IsWindows && (IsX86_64 || IsAArch64)) {
585 else if (IsMacOS && IsAArch64)
589 else if (IsLoongArch64)
596 else if (IsHaiku && IsX86_64)
618 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
619 !IsRISCV64 && !IsLoongArch64 &&
620 !(Mapping.Offset & (Mapping.Offset - 1)) &&
622 Mapping.InGlobal =
ClWithIfunc && IsAndroid && IsArmOrThumb;
629 int *MappingScale,
bool *OrShadowOffset) {
631 *ShadowBase = Mapping.Offset;
632 *MappingScale = Mapping.Scale;
633 *OrShadowOffset = Mapping.OrShadowOffset;
654 if (!
F.getMemoryEffects()
656 .doesNotAccessMemory() &&
658 F.setMemoryEffects(
F.getMemoryEffects() |
666 F.setMemoryEffects(
F.getMemoryEffects() |
671 if (
A.hasAttribute(Attribute::WriteOnly)) {
672 A.removeAttr(Attribute::WriteOnly);
680 F.addFnAttr(Attribute::NoBuiltin);
701 return std::max(32U, 1U << MappingScale);
719class RuntimeCallInserter {
721 bool TrackInsertedCalls =
false;
725 RuntimeCallInserter(Function &Fn) : OwnerFn(&Fn) {
727 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
728 if (isScopedEHPersonality(Personality))
729 TrackInsertedCalls = true;
733 ~RuntimeCallInserter() {
734 if (InsertedCalls.
empty())
736 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
738 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
739 for (CallInst *CI : InsertedCalls) {
741 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
743 "Instruction doesn't belong to the expected Function!");
751 if (Colors.
size() != 1) {
753 "Instruction's BasicBlock is not monochromatic");
760 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
764 OB, CI->getIterator());
765 NewCall->copyMetadata(*CI);
766 CI->replaceAllUsesWith(NewCall);
767 CI->eraseFromParent();
772 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
774 const Twine &
Name =
"") {
777 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
778 if (TrackInsertedCalls)
779 InsertedCalls.push_back(Inst);
785struct AddressSanitizer {
786 AddressSanitizer(
Module &M,
const StackSafetyGlobalInfo *SSGI,
787 int InstrumentationWithCallsThreshold,
788 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
789 bool Recover =
false,
bool UseAfterScope =
false,
791 AsanDetectStackUseAfterReturnMode::Runtime)
800 InstrumentationWithCallsThreshold(
803 : InstrumentationWithCallsThreshold),
806 : MaxInlinePoisoningSize) {
807 C = &(
M.getContext());
808 DL = &
M.getDataLayout();
809 LongSize =
M.getDataLayout().getPointerSizeInBits();
810 IntptrTy = Type::getIntNTy(*
C, LongSize);
811 PtrTy = PointerType::getUnqual(*
C);
813 TargetTriple =
M.getTargetTriple();
817 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
825 bool isInterestingAlloca(
const AllocaInst &AI);
827 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
829 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
830 const TargetTransformInfo *
TTI);
832 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
833 InterestingMemoryOperand &O,
bool UseCalls,
834 const DataLayout &
DL, RuntimeCallInserter &RTCI);
835 void instrumentPointerComparisonOrSubtraction(Instruction *
I,
836 RuntimeCallInserter &RTCI);
838 Value *Addr, MaybeAlign Alignment,
839 uint32_t TypeStoreSize,
bool IsWrite,
840 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
841 RuntimeCallInserter &RTCI);
842 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
843 Instruction *InsertBefore,
Value *Addr,
844 uint32_t TypeStoreSize,
bool IsWrite,
845 Value *SizeArgument);
848 void instrumentUnusualSizeOrAlignment(Instruction *
I,
849 Instruction *InsertBefore,
Value *Addr,
850 TypeSize TypeStoreSize,
bool IsWrite,
851 Value *SizeArgument,
bool UseCalls,
853 RuntimeCallInserter &RTCI);
854 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
857 MaybeAlign Alignment,
unsigned Granularity,
858 Type *OpType,
bool IsWrite,
859 Value *SizeArgument,
bool UseCalls,
860 uint32_t Exp, RuntimeCallInserter &RTCI);
862 Value *ShadowValue, uint32_t TypeStoreSize);
864 bool IsWrite,
size_t AccessSizeIndex,
865 Value *SizeArgument, uint32_t Exp,
866 RuntimeCallInserter &RTCI);
867 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
869 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
870 bool instrumentFunction(Function &
F,
const TargetLibraryInfo *TLI,
871 const TargetTransformInfo *
TTI);
872 bool maybeInsertAsanInitAtFunctionEntry(Function &
F);
873 bool maybeInsertDynamicShadowAtFunctionEntry(Function &
F);
874 void markEscapedLocalAllocas(Function &
F);
875 void markCatchParametersAsUninteresting(Function &
F);
878 friend struct FunctionStackPoisoner;
880 void initializeCallbacks(
const TargetLibraryInfo *TLI);
882 bool LooksLikeCodeInBug11395(Instruction *
I);
883 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
884 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
885 TypeSize TypeStoreSize)
const;
888 struct FunctionStateRAII {
889 AddressSanitizer *
Pass;
891 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
893 "last pass forgot to clear cache");
897 ~FunctionStateRAII() {
898 Pass->LocalDynamicShadow =
nullptr;
899 Pass->ProcessedAllocas.clear();
905 const DataLayout *
DL;
915 ShadowMapping Mapping;
916 FunctionCallee AsanHandleNoReturnFunc;
917 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
925 FunctionCallee AsanErrorCallbackSized[2][2];
926 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
928 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
929 Value *LocalDynamicShadow =
nullptr;
930 const StackSafetyGlobalInfo *SSGI;
931 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
933 FunctionCallee AMDGPUAddressShared;
934 FunctionCallee AMDGPUAddressPrivate;
935 int InstrumentationWithCallsThreshold;
936 uint32_t MaxInlinePoisoningSize;
939class ModuleAddressSanitizer {
941 ModuleAddressSanitizer(
Module &M,
bool InsertVersionCheck,
942 bool CompileKernel =
false,
bool Recover =
false,
943 bool UseGlobalsGC =
true,
bool UseOdrIndicator =
true,
951 : InsertVersionCheck),
953 UseGlobalsGC(UseGlobalsGC &&
ClUseGlobalsGC && !this->CompileKernel),
968 UseCtorComdat(UseGlobalsGC &&
ClWithComdat && !this->CompileKernel),
969 DestructorKind(DestructorKind),
973 C = &(
M.getContext());
974 int LongSize =
M.getDataLayout().getPointerSizeInBits();
975 IntptrTy = Type::getIntNTy(*
C, LongSize);
976 PtrTy = PointerType::getUnqual(*
C);
977 TargetTriple =
M.getTargetTriple();
982 assert(this->DestructorKind != AsanDtorKind::Invalid);
985 bool instrumentModule();
988 void initializeCallbacks();
990 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
997 const std::string &UniqueModuleId);
1002 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
1006 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
1007 StringRef OriginalName);
1008 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
1009 StringRef InternalSuffix);
1012 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
1013 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
1014 bool ShouldUseMachOGlobalsSection()
const;
1015 StringRef getGlobalMetadataSection()
const;
1016 void poisonOneInitializer(Function &GlobalInit);
1017 void createInitializerPoisonCalls();
1018 uint64_t getMinRedzoneSizeForGlobal()
const {
1022 int GetAsanVersion()
const;
1023 GlobalVariable *getOrCreateModuleName();
1027 bool InsertVersionCheck;
1030 bool UsePrivateAlias;
1031 bool UseOdrIndicator;
1038 Triple TargetTriple;
1039 ShadowMapping Mapping;
1040 FunctionCallee AsanPoisonGlobals;
1041 FunctionCallee AsanUnpoisonGlobals;
1042 FunctionCallee AsanRegisterGlobals;
1043 FunctionCallee AsanUnregisterGlobals;
1044 FunctionCallee AsanRegisterImageGlobals;
1045 FunctionCallee AsanUnregisterImageGlobals;
1046 FunctionCallee AsanRegisterElfGlobals;
1047 FunctionCallee AsanUnregisterElfGlobals;
1049 Function *AsanCtorFunction =
nullptr;
1050 Function *AsanDtorFunction =
nullptr;
1051 GlobalVariable *ModuleName =
nullptr;
1063struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
1065 AddressSanitizer &ASan;
1066 RuntimeCallInserter &RTCI;
1071 ShadowMapping Mapping;
1075 SmallVector<Instruction *, 8> RetVec;
1079 FunctionCallee AsanSetShadowFunc[0x100] = {};
1080 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
1081 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
1084 struct AllocaPoisonCall {
1085 IntrinsicInst *InsBefore;
1095 AllocaInst *DynamicAllocaLayout =
nullptr;
1096 IntrinsicInst *LocalEscapeCall =
nullptr;
1098 bool HasInlineAsm =
false;
1099 bool HasReturnsTwiceCall =
false;
1102 FunctionStackPoisoner(Function &
F, AddressSanitizer &ASan,
1103 RuntimeCallInserter &RTCI)
1104 :
F(
F), ASan(ASan), RTCI(RTCI),
1106 IntptrTy(ASan.IntptrTy),
1108 Mapping(ASan.Mapping),
1116 copyArgsPassedByValToAllocas();
1121 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
1123 initializeCallbacks(*
F.getParent());
1125 processDynamicAllocas();
1126 processStaticAllocas();
1137 void copyArgsPassedByValToAllocas();
1142 void processStaticAllocas();
1143 void processDynamicAllocas();
1145 void createDynamicAllocasInitStorage();
1150 void visitReturnInst(ReturnInst &RI) {
1151 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
1158 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
1161 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
1163 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
1164 Value *SavedStack) {
1173 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
1179 RTCI.createRuntimeCall(
1180 IRB, AsanAllocasUnpoisonFunc,
1181 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
1185 void unpoisonDynamicAllocas() {
1186 for (Instruction *Ret : RetVec)
1187 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
1189 for (Instruction *StackRestoreInst : StackRestoreVec)
1190 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
1191 StackRestoreInst->getOperand(0));
1204 void handleDynamicAllocaCall(AllocaInst *AI);
1207 void visitAllocaInst(AllocaInst &AI) {
1212 (STy && STy->containsHomogeneousScalableVectorTypes())) {
1216 if (AllocaVec.
empty())
1232 void visitIntrinsicInst(IntrinsicInst &
II) {
1234 if (
ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
1235 if (
ID == Intrinsic::localescape) LocalEscapeCall = &
II;
1236 if (!ASan.UseAfterScope)
1238 if (!
II.isLifetimeStartOrEnd())
1243 if (!AI || !ASan.isInterestingAlloca(*AI))
1253 bool DoPoison = (
ID == Intrinsic::lifetime_end);
1254 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
1256 StaticAllocaPoisonCallVec.
push_back(APC);
1258 DynamicAllocaPoisonCallVec.
push_back(APC);
1261 void visitCallBase(CallBase &CB) {
1263 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1264 HasReturnsTwiceCall |= CI->canReturnTwice();
1269 void initializeCallbacks(
Module &M);
1274 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1276 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1279 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1280 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1285 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1288 Instruction *ThenTerm,
Value *ValueIfFalse);
1296 OS, MapClassName2PassName);
1298 if (Options.CompileKernel)
1300 if (Options.UseAfterScope)
1301 OS <<
"use-after-scope";
1309 : Options(Options), UseGlobalGC(UseGlobalGC),
1310 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1311 ConstructorKind(ConstructorKind) {}
1320 ModuleAddressSanitizer ModuleSanitizer(
1321 M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
1322 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
1334 if (
F.getName().starts_with(
"__asan_"))
1336 if (
F.isPresplitCoroutine())
1338 AddressSanitizer FunctionSanitizer(
1339 M, SSGI, Options.InstrumentationWithCallsThreshold,
1340 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1341 Options.UseAfterScope, Options.UseAfterReturn);
1344 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1346 Modified |= ModuleSanitizer.instrumentModule();
1367 if (
G->getName().starts_with(
"llvm.") ||
1369 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1371 G->getName().starts_with(
"__llvm_rtti_proxy"))
1387 if (AddrSpace == 3 || AddrSpace == 5)
1402 return AddrSpace == 0;
1407 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1408 if (Mapping.Offset == 0)
return Shadow;
1411 if (LocalDynamicShadow)
1412 ShadowBase = LocalDynamicShadow;
1414 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1415 if (Mapping.OrShadowOffset)
1416 return IRB.
CreateOr(Shadow, ShadowBase);
1418 return IRB.
CreateAdd(Shadow, ShadowBase);
1423 RuntimeCallInserter &RTCI) {
1426 RTCI.createRuntimeCall(
1432 RTCI.createRuntimeCall(
1438 MI->eraseFromParent();
1442bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1443 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1446 return It->getSecond();
1448 bool IsInteresting =
1461 !(SSGI && SSGI->
isSafe(AI)));
1463 It->second = IsInteresting;
1464 return IsInteresting;
1494void AddressSanitizer::getInterestingMemoryOperands(
1498 if (LocalDynamicShadow ==
I)
1504 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1505 LI->getType(), LI->getAlign());
1510 SI->getValueOperand()->getType(),
SI->getAlign());
1514 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1515 RMW->getValOperand()->getType(), std::nullopt);
1519 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1520 XCHG->getCompareOperand()->getType(),
1523 switch (CI->getIntrinsicID()) {
1524 case Intrinsic::masked_load:
1525 case Intrinsic::masked_store:
1526 case Intrinsic::masked_gather:
1527 case Intrinsic::masked_scatter: {
1528 bool IsWrite = CI->getType()->isVoidTy();
1530 unsigned OpOffset = IsWrite ? 1 : 0;
1534 auto BasePtr = CI->getOperand(OpOffset);
1535 if (ignoreAccess(
I, BasePtr))
1537 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1539 Value *
Mask = CI->getOperand(1 + OpOffset);
1540 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1543 case Intrinsic::masked_expandload:
1544 case Intrinsic::masked_compressstore: {
1545 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1546 unsigned OpOffset = IsWrite ? 1 : 0;
1549 auto BasePtr = CI->getOperand(OpOffset);
1550 if (ignoreAccess(
I, BasePtr))
1553 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1556 Value *
Mask = CI->getOperand(1 + OpOffset);
1559 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1560 Value *EVL =
IB.CreateAddReduce(ExtMask);
1561 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1562 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1566 case Intrinsic::vp_load:
1567 case Intrinsic::vp_store:
1568 case Intrinsic::experimental_vp_strided_load:
1569 case Intrinsic::experimental_vp_strided_store: {
1571 unsigned IID = CI->getIntrinsicID();
1572 bool IsWrite = CI->getType()->isVoidTy();
1575 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1576 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1577 MaybeAlign Alignment = VPI->getOperand(PtrOpNo)->getPointerAlignment(*
DL);
1578 Value *Stride =
nullptr;
1579 if (IID == Intrinsic::experimental_vp_strided_store ||
1580 IID == Intrinsic::experimental_vp_strided_load) {
1581 Stride = VPI->getOperand(PtrOpNo + 1);
1588 Alignment =
Align(1);
1590 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1591 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1595 case Intrinsic::vp_gather:
1596 case Intrinsic::vp_scatter: {
1598 unsigned IID = CI->getIntrinsicID();
1599 bool IsWrite = IID == Intrinsic::vp_scatter;
1602 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1603 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1604 MaybeAlign Alignment = VPI->getPointerAlignment();
1605 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1606 VPI->getMaskParam(),
1607 VPI->getVectorLengthParam());
1613 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1617 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1619 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1621 Type *Ty = CI->getParamByValType(ArgNo);
1637 if (!Cmp->isRelational())
1651 if (BO->getOpcode() != Instruction::Sub)
1664 if (!
G->hasInitializer())
1667 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1673void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1677 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1678 for (
Value *&i : Param) {
1679 if (i->getType()->isPointerTy())
1682 RTCI.createRuntimeCall(IRB,
F, Param);
1688 TypeSize TypeStoreSize,
bool IsWrite,
1689 Value *SizeArgument,
bool UseCalls,
1690 uint32_t Exp, RuntimeCallInserter &RTCI) {
1695 switch (FixedSize) {
1701 if (!Alignment || *Alignment >= Granularity ||
1702 *Alignment >= FixedSize / 8)
1703 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1704 FixedSize, IsWrite,
nullptr, UseCalls,
1708 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1709 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1712void AddressSanitizer::instrumentMaskedLoadOrStore(
1715 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1716 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1717 RuntimeCallInserter &RTCI) {
1719 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1720 auto Zero = ConstantInt::get(IntptrTy, 0);
1728 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1730 IB.SetInsertPoint(LoopInsertBefore);
1732 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1735 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1736 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1738 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1743 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1747 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1748 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1749 if (MaskElemC->isZero())
1755 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1756 MaskElem, &*IRB.GetInsertPoint(), false);
1757 IRB.SetInsertPoint(ThenTerm);
1760 Value *InstrumentedAddress;
1763 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1764 "Expected vector of pointer.");
1765 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1766 }
else if (Stride) {
1773 Alignment, Granularity, ElemTypeSize, IsWrite,
1774 SizeArgument, UseCalls, Exp, RTCI);
1781 RuntimeCallInserter &RTCI) {
1782 Value *Addr =
O.getPtr();
1802 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1803 NumOptimizedAccessesToGlobalVar++;
1811 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1812 NumOptimizedAccessesToStackVar++;
1818 NumInstrumentedWrites++;
1820 NumInstrumentedReads++;
1822 if (
O.MaybeByteOffset) {
1827 if (TargetTriple.isRISCV()) {
1832 static_cast<unsigned>(LongSize)) {
1841 unsigned Granularity = 1 << Mapping.Scale;
1843 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1844 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1845 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1846 UseCalls, Exp, RTCI);
1849 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1850 UseCalls, Exp, RTCI);
1855 Value *Addr,
bool IsWrite,
1856 size_t AccessSizeIndex,
1857 Value *SizeArgument,
1859 RuntimeCallInserter &RTCI) {
1865 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1866 {Addr, SizeArgument});
1868 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1869 {Addr, SizeArgument, ExpVal});
1872 Call = RTCI.createRuntimeCall(
1873 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1875 Call = RTCI.createRuntimeCall(
1876 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1885 uint32_t TypeStoreSize) {
1886 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1888 Value *LastAccessedByte =
1889 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1891 if (TypeStoreSize / 8 > 1)
1893 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1896 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1901Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1903 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1910 return InsertBefore;
1915 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1917 Value *AddrSpaceZeroLanding =
1920 return InsertBefore;
1936 Trm->getParent()->setName(
"asan.report");
1947void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1950 uint32_t TypeStoreSize,
bool IsWrite,
1951 Value *SizeArgument,
bool UseCalls,
1953 RuntimeCallInserter &RTCI) {
1954 if (TargetTriple.isAMDGPU()) {
1955 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1956 TypeStoreSize, IsWrite, SizeArgument);
1965 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1968 ConstantInt::get(
Int32Ty, AccessInfo.Packed)});
1975 RTCI.createRuntimeCall(
1976 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1978 RTCI.createRuntimeCall(
1979 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1980 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
1987 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1988 const uint64_t ShadowAlign =
1989 std::max<uint64_t>(Alignment.
valueOrOne().
value() >> Mapping.Scale, 1);
1994 size_t Granularity = 1ULL << Mapping.Scale;
1997 bool GenSlowPath = (
ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
1999 if (TargetTriple.isAMDGCN()) {
2001 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2004 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2005 }
else if (GenSlowPath) {
2012 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2027 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2036void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2038 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
2039 uint32_t Exp, RuntimeCallInserter &RTCI) {
2047 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2050 RTCI.createRuntimeCall(
2051 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2065void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
2071 Value *ModuleNameAddr =
2073 IRB.
CreateCall(AsanPoisonGlobals, ModuleNameAddr);
2076 for (
auto &BB : GlobalInit)
2081void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2101 poisonOneInitializer(*
F);
2107ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
2112 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
2124bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
2125 Type *Ty =
G->getValueType();
2128 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
2130 if (!Ty->
isSized())
return false;
2131 if (!
G->hasInitializer())
return false;
2138 if (
G->isThreadLocal())
return false;
2140 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
2146 if (!TargetTriple.isOSBinFormatCOFF()) {
2147 if (!
G->hasExactDefinition() ||
G->hasComdat())
2151 if (
G->isInterposable())
2155 if (
G->hasAvailableExternallyLinkage())
2162 switch (
C->getSelectionKind()) {
2173 if (
G->hasSection()) {
2183 if (Section ==
"llvm.metadata")
return false;
2190 if (
Section.starts_with(
".preinit_array") ||
2191 Section.starts_with(
".init_array") ||
2192 Section.starts_with(
".fini_array")) {
2198 if (TargetTriple.isOSBinFormatELF()) {
2212 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2213 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2218 if (TargetTriple.isOSBinFormatMachO()) {
2220 unsigned TAA = 0, StubSize = 0;
2223 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2228 if (ParsedSegment ==
"__OBJC" ||
2229 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2241 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2254 if (CompileKernel) {
2257 if (
G->getName().starts_with(
"__"))
2267bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2268 if (!TargetTriple.isOSBinFormatMachO())
2271 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2273 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2275 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2277 if (TargetTriple.isDriverKit())
2279 if (TargetTriple.isXROS())
2285StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2286 switch (TargetTriple.getObjectFormat()) {
2296 "ModuleAddressSanitizer not implemented for object file format");
2303void ModuleAddressSanitizer::initializeCallbacks() {
2309 AsanUnpoisonGlobals =
2313 AsanRegisterGlobals =
M.getOrInsertFunction(
2315 AsanUnregisterGlobals =
M.getOrInsertFunction(
2320 AsanRegisterImageGlobals =
M.getOrInsertFunction(
2322 AsanUnregisterImageGlobals =
M.getOrInsertFunction(
2325 AsanRegisterElfGlobals =
2327 IntptrTy, IntptrTy, IntptrTy);
2328 AsanUnregisterElfGlobals =
2330 IntptrTy, IntptrTy, IntptrTy);
2335void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2340 if (!
G->hasName()) {
2344 G->setName(
genName(
"anon_global"));
2347 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2348 std::string
Name = std::string(
G->getName());
2349 Name += InternalSuffix;
2350 C =
M.getOrInsertComdat(Name);
2352 C =
M.getOrInsertComdat(
G->getName());
2358 if (TargetTriple.isOSBinFormatCOFF()) {
2360 if (
G->hasPrivateLinkage())
2373ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2375 auto Linkage = TargetTriple.isOSBinFormatMachO()
2381 Metadata->setSection(getGlobalMetadataSection());
2388Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2392 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2400void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2404 auto &
DL =
M.getDataLayout();
2407 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2408 Constant *Initializer = MetadataInitializers[i];
2412 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2418 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2420 "global metadata will not be padded appropriately");
2423 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2428 if (!MetadataGlobals.empty())
2432void ModuleAddressSanitizer::instrumentGlobalsELF(
2435 const std::string &UniqueModuleId) {
2442 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2445 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2448 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2450 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2453 if (UseComdatForGlobalsGC)
2454 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2459 if (!MetadataGlobals.empty())
2476 "__start_" + getGlobalMetadataSection());
2480 "__stop_" + getGlobalMetadataSection());
2494 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2501void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2512 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2513 Constant *Initializer = MetadataInitializers[i];
2519 auto LivenessBinder =
2524 Twine(
"__asan_binder_") +
G->getName());
2525 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2526 LivenessGlobals[i] = Liveness;
2533 if (!LivenessGlobals.empty())
2555 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2560void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2564 unsigned N = ExtendedGlobals.
size();
2574 if (Mapping.Scale > 3)
2575 AllGlobals->setAlignment(
Align(1ULL << Mapping.Scale));
2580 ConstantInt::get(IntptrTy,
N)});
2586 IrbDtor.CreateCall(AsanUnregisterGlobals,
2588 ConstantInt::get(IntptrTy,
N)});
2597void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2602 if (CompileKernel) {
2603 for (
auto &GA :
M.aliases()) {
2605 AliasedGlobalExclusions.
insert(GV);
2610 for (
auto &
G :
M.globals()) {
2611 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2615 size_t n = GlobalsToChange.
size();
2616 auto &
DL =
M.getDataLayout();
2630 IntptrTy, IntptrTy, IntptrTy);
2634 for (
size_t i = 0; i < n; i++) {
2638 if (
G->hasSanitizerMetadata())
2639 MD =
G->getSanitizerMetadata();
2644 std::string NameForGlobal =
G->getName().str();
2649 Type *Ty =
G->getValueType();
2650 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2663 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2664 G->getThreadLocalMode(),
G->getAddressSpace());
2674 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2677 if (Seq && Seq->isCString())
2678 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2685 G->replaceAllUsesWith(NewGlobal);
2687 G->eraseFromParent();
2688 NewGlobals[i] = NewGlobal;
2693 bool CanUsePrivateAliases =
2694 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2695 TargetTriple.isOSBinFormatWasm();
2696 if (CanUsePrivateAliases && UsePrivateAlias) {
2699 InstrumentedGlobal =
2706 }
else if (UseOdrIndicator) {
2709 auto *ODRIndicatorSym =
2718 ODRIndicatorSym->setAlignment(
Align(1));
2725 ConstantInt::get(IntptrTy, SizeInBytes),
2726 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2729 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2734 Initializers[i] = Initializer;
2740 for (
size_t i = 0; i < n; i++) {
2742 if (
G->getName().empty())
continue;
2747 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2754 }
else if (n == 0) {
2757 *CtorComdat = TargetTriple.isOSBinFormatELF();
2759 *CtorComdat =
false;
2760 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2761 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2762 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2763 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2765 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2771 createInitializerPoisonCalls();
2777ModuleAddressSanitizer::getRedzoneSizeForGlobal(uint64_t SizeInBytes)
const {
2778 constexpr uint64_t kMaxRZ = 1 << 18;
2779 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2782 if (SizeInBytes <= MinRZ / 2) {
2786 RZ = MinRZ - SizeInBytes;
2789 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2792 if (SizeInBytes % MinRZ)
2793 RZ += MinRZ - (SizeInBytes % MinRZ);
2796 assert((RZ + SizeInBytes) % MinRZ == 0);
2801int ModuleAddressSanitizer::GetAsanVersion()
const {
2802 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2803 bool isAndroid =
M.getTargetTriple().isAndroid();
2807 Version += (LongSize == 32 && isAndroid);
2822bool ModuleAddressSanitizer::instrumentModule() {
2823 initializeCallbacks();
2831 if (CompileKernel) {
2836 std::string AsanVersion = std::to_string(GetAsanVersion());
2837 std::string VersionCheckName =
2839 std::tie(AsanCtorFunction, std::ignore) =
2842 {}, VersionCheckName);
2846 bool CtorComdat =
true;
2849 if (AsanCtorFunction) {
2850 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2851 instrumentGlobals(IRB, &CtorComdat);
2854 instrumentGlobals(IRB, &CtorComdat);
2863 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2864 if (AsanCtorFunction) {
2868 if (AsanDtorFunction) {
2873 if (AsanCtorFunction)
2875 if (AsanDtorFunction)
2886 for (
int Exp = 0;
Exp < 2;
Exp++) {
2887 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2888 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2889 const std::string ExpStr =
Exp ?
"exp_" :
"";
2890 const std::string EndingStr = Recover ?
"_noabort" :
"";
2900 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2901 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2902 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2905 AsanErrorCallbackSized[AccessIsWrite][
Exp] =
M.getOrInsertFunction(
2909 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
M.getOrInsertFunction(
2914 AccessSizeIndex++) {
2915 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2916 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2917 M.getOrInsertFunction(
2921 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2922 M.getOrInsertFunction(
2929 const std::string MemIntrinCallbackPrefix =
2933 AsanMemmove =
M.getOrInsertFunction(MemIntrinCallbackPrefix +
"memmove",
2934 PtrTy, PtrTy, PtrTy, IntptrTy);
2935 AsanMemcpy =
M.getOrInsertFunction(MemIntrinCallbackPrefix +
"memcpy", PtrTy,
2936 PtrTy, PtrTy, IntptrTy);
2937 AsanMemset =
M.getOrInsertFunction(MemIntrinCallbackPrefix +
"memset",
2941 AsanHandleNoReturnFunc =
2944 AsanPtrCmpFunction =
2946 AsanPtrSubFunction =
2948 if (Mapping.InGlobal)
2949 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
2952 AMDGPUAddressShared =
2954 AMDGPUAddressPrivate =
2958bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2966 if (
F.getName().contains(
" load]")) {
2976bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
2982 if (Mapping.InGlobal) {
2990 LocalDynamicShadow =
2991 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
2993 LocalDynamicShadow =
2997 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
2999 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
3004void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
3009 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
3013 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
3019 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
3021 for (
Value *Arg :
II->args()) {
3024 "non-static alloca arg to localescape");
3025 ProcessedAllocas[AI] =
false;
3034void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
3040 for (
Value *Operand : CatchPad->arg_operands())
3042 ProcessedAllocas[AI] =
false;
3048bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
3049 bool ShouldInstrument =
3053 return !ShouldInstrument;
3056bool AddressSanitizer::instrumentFunction(
Function &
F,
3059 bool FunctionModified =
false;
3062 if (
F.hasFnAttribute(Attribute::Naked))
3063 return FunctionModified;
3068 if (maybeInsertAsanInitAtFunctionEntry(
F))
3069 FunctionModified =
true;
3072 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
3074 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3075 return FunctionModified;
3079 initializeCallbacks(TLI);
3081 FunctionStateRAII CleanupObj(
this);
3083 RuntimeCallInserter RTCI(
F);
3085 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
3089 markEscapedLocalAllocas(
F);
3091 if (TargetTriple.isOSWindows())
3092 markCatchParametersAsUninteresting(
F);
3104 for (
auto &BB :
F) {
3106 TempsToInstrument.
clear();
3107 int NumInsnsPerBB = 0;
3108 for (
auto &Inst : BB) {
3109 if (LooksLikeCodeInBug11395(&Inst))
return false;
3116 if (!InterestingOperands.
empty()) {
3117 for (
auto &Operand : InterestingOperands) {
3119 Value *Ptr = Operand.getPtr();
3123 if (Operand.MaybeMask) {
3124 if (TempsToInstrument.
count(Ptr))
3127 if (!TempsToInstrument.
insert(Ptr).second)
3131 OperandsToInstrument.
push_back(Operand);
3138 PointerComparisonsOrSubtracts.
push_back(&Inst);
3146 TempsToInstrument.
clear();
3157 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3158 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
3159 (
unsigned)InstrumentationWithCallsThreshold);
3164 int NumInstrumented = 0;
3165 for (
auto &Operand : OperandsToInstrument) {
3166 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3167 instrumentMop(ObjSizeVis, Operand, UseCalls,
3168 F.getDataLayout(), RTCI);
3169 FunctionModified =
true;
3171 for (
auto *Inst : IntrinToInstrument) {
3172 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3173 instrumentMemIntrinsic(Inst, RTCI);
3174 FunctionModified =
true;
3177 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3178 bool ChangedStack = FSP.runOnFunction();
3182 for (
auto *CI : NoReturnCalls) {
3184 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3187 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3188 instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3189 FunctionModified =
true;
3192 if (ChangedStack || !NoReturnCalls.empty())
3193 FunctionModified =
true;
3195 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3198 return FunctionModified;
3204bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3205 if (LongSize != 32)
return false;
3214void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
3218 const char *MallocNameTemplate =
3223 std::string Suffix =
itostr(Index);
3224 AsanStackMallocFunc[
Index] =
M.getOrInsertFunction(
3225 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3226 AsanStackFreeFunc[
Index] =
3231 if (ASan.UseAfterScope) {
3232 AsanPoisonStackMemoryFunc =
M.getOrInsertFunction(
3234 AsanUnpoisonStackMemoryFunc =
M.getOrInsertFunction(
3238 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3239 0xf3, 0xf5, 0xf8}) {
3240 std::ostringstream
Name;
3242 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3243 AsanSetShadowFunc[Val] =
3244 M.getOrInsertFunction(
Name.str(), IRB.
getVoidTy(), IntptrTy, IntptrTy);
3247 AsanAllocaPoisonFunc =
M.getOrInsertFunction(
3249 AsanAllocasUnpoisonFunc =
M.getOrInsertFunction(
3255 size_t Begin,
size_t End,
3257 Value *ShadowBase) {
3261 const size_t LargestStoreSizeInBytes =
3262 std::min<size_t>(
sizeof(uint64_t), ASan.LongSize / 8);
3264 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3270 for (
size_t i = Begin; i < End;) {
3271 if (!ShadowMask[i]) {
3277 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3279 while (StoreSizeInBytes > End - i)
3280 StoreSizeInBytes /= 2;
3283 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3284 while (j <= StoreSizeInBytes / 2)
3285 StoreSizeInBytes /= 2;
3289 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3291 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
3293 Val = (Val << 8) | ShadowBytes[i + j];
3296 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3302 i += StoreSizeInBytes;
3309 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3314 size_t Begin,
size_t End,
3317 size_t Done = Begin;
3318 for (
size_t i = Begin, j = Begin + 1; i < End; i =
j++) {
3319 if (!ShadowMask[i]) {
3323 uint8_t Val = ShadowBytes[i];
3324 if (!AsanSetShadowFunc[Val])
3328 for (;
j < End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3331 if (j - i >= ASan.MaxInlinePoisoningSize) {
3332 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3333 RTCI.createRuntimeCall(
3334 IRB, AsanSetShadowFunc[Val],
3335 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3336 ConstantInt::get(IntptrTy, j - i)});
3341 copyToShadowInline(ShadowMask, ShadowBytes,
Done, End, IRB, ShadowBase);
3349 for (
int i = 0;; i++, MaxSize *= 2)
3350 if (LocalStackSize <= MaxSize)
return i;
3354void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3356 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3364 if (Arg.hasByValAttr()) {
3365 Type *Ty = Arg.getParamByValType();
3366 const Align Alignment =
3367 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3371 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3374 Arg.replaceAllUsesWith(AI);
3376 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3377 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3385 Value *ValueIfFalse) {
3388 PHI->addIncoming(ValueIfFalse, CondBlock);
3390 PHI->addIncoming(ValueIfTrue, ThenBlock);
3394Value *FunctionStackPoisoner::createAllocaForLayout(
3403 nullptr,
"MyAlloca");
3407 uint64_t FrameAlignment = std::max(
L.FrameAlignment, uint64_t(
ClRealignStack));
3412void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3415 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3420void FunctionStackPoisoner::processDynamicAllocas() {
3427 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3430 assert(ASan.isInterestingAlloca(*APC.AI));
3431 assert(!APC.AI->isStaticAlloca());
3434 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3441 createDynamicAllocasInitStorage();
3442 for (
auto &AI : DynamicAllocaVec)
3443 handleDynamicAllocaCall(AI);
3444 unpoisonDynamicAllocas();
3456 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3473 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3476 Value *Val = Store->getValueOperand();
3478 bool IsArgInitViaCast =
3483 Val == It->getPrevNode();
3484 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3488 if (IsArgInitViaCast)
3503 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3506 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3510 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3513 auto MetadataString =
3515 if (MetadataString->getString() ==
"alloca_name_altered")
3524void FunctionStackPoisoner::processStaticAllocas() {
3525 if (AllocaVec.
empty()) {
3530 int StackMallocIdx = -1;
3532 if (
auto SP =
F.getSubprogram())
3533 EntryDebugLocation =
3542 auto InsBeforeB = InsBefore->
getParent();
3543 assert(InsBeforeB == &
F.getEntryBlock());
3544 for (
auto *AI : StaticAllocasToMoveUp)
3555 ArgInitInst->moveBefore(InsBefore->
getIterator());
3558 if (LocalEscapeCall)
3566 ASan.getAllocaSizeInBytes(*AI),
3577 uint64_t Granularity = 1ULL << Mapping.Scale;
3578 uint64_t MinHeaderSize = std::max((uint64_t)ASan.LongSize / 2, Granularity);
3584 for (
auto &
Desc : SVD)
3588 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3591 assert(ASan.isInterestingAlloca(*APC.AI));
3592 assert(APC.AI->isStaticAlloca());
3597 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3598 if (LifetimeLoc->getFile() == FnLoc->getFile())
3599 if (
unsigned Line = LifetimeLoc->getLine())
3600 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3606 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3607 uint64_t LocalStackSize =
L.FrameSize;
3608 bool DoStackMalloc =
3618 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3619 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3621 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3622 Value *StaticAlloca =
3623 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3625 Value *FakeStackPtr;
3626 Value *FakeStackInt;
3627 Value *LocalStackBase;
3628 Value *LocalStackBaseAlloca;
3631 if (DoStackMalloc) {
3632 LocalStackBaseAlloca =
3633 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3640 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3650 Value *FakeStackValue =
3651 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3652 ConstantInt::get(IntptrTy, LocalStackSize));
3654 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3655 Term, ConstantInt::get(IntptrTy, 0));
3663 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3664 ConstantInt::get(IntptrTy, LocalStackSize));
3667 Value *NoFakeStack =
3672 Value *AllocaValue =
3673 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3677 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3678 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3686 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3687 LocalStackBaseAlloca = LocalStackBase;
3692 for (
const auto &
Desc : SVD) {
3696 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3707 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3715 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3722 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3725 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3727 if (!StaticAllocaPoisonCallVec.empty()) {
3731 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3734 size_t Begin =
Desc.Offset /
L.Granularity;
3735 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3738 copyToShadow(ShadowAfterScope,
3739 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3745 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3748 if (
I->isLifetimeStartOrEnd())
3749 I->eraseFromParent();
3762 if (DoStackMalloc) {
3763 assert(StackMallocIdx >= 0);
3780 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3782 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3784 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3786 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3788 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3789 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3790 IRBPoison.CreateStore(
3792 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3795 RTCI.createRuntimeCall(
3796 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3797 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3801 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3803 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3808 for (
auto *AI : AllocaVec)
3812void FunctionStackPoisoner::poisonAlloca(
Value *V, uint64_t
Size,
3816 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3817 RTCI.createRuntimeCall(
3818 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3819 {AddrArg, SizeArg});
3830void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3838 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3872 ConstantInt::get(IntptrTy, Alignment.
value()));
3875 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3886 if (
I->isLifetimeStartOrEnd())
3887 I->eraseFromParent();
3919 Size - uint64_t(
Offset) >= TypeStoreSize / 8;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > ClUseStackSafety("stack-tagging-use-stack-safety", cl::Hidden, cl::init(true), cl::desc("Use Stack Safety analysis results"))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void findStoresToUninstrumentedArgAllocas(AddressSanitizer &ASan, Instruction &InsBefore, SmallVectorImpl< Instruction * > &InitInsts)
Collect instructions in the entry block after InsBefore which initialize permanent storage for a func...
static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I, Instruction *InsertBefore, Value *Addr, MaybeAlign Alignment, unsigned Granularity, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp, RuntimeCallInserter &RTCI)
static const uint64_t kDefaultShadowScale
const char kAMDGPUUnreachableName[]
constexpr size_t kAccessSizeIndexMask
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClUsePrivateAlias("asan-use-private-alias", cl::desc("Use private aliases for global variables"), cl::Hidden, cl::init(true))
static const uint64_t kPS_ShadowOffset64
static const uint64_t kFreeBSD_ShadowOffset32
constexpr size_t kIsWriteShift
static const uint64_t kSmallX86_64ShadowOffsetAlignMask
static bool isInterestingPointerSubtraction(Instruction *I)
const char kAMDGPUAddressSharedName[]
const char kAsanStackFreeNameTemplate[]
constexpr size_t kCompileKernelMask
static cl::opt< bool > ClForceDynamicShadow("asan-force-dynamic-shadow", cl::desc("Load shadow address into a local variable for each function"), cl::Hidden, cl::init(false))
const char kAsanOptionDetectUseAfterReturn[]
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static const uint64_t kRISCV64_ShadowOffset64
static cl::opt< bool > ClInsertVersionCheck("asan-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
const char kAsanSetShadowPrefix[]
static cl::opt< AsanDtorKind > ClOverrideDestructorKind("asan-destructor-kind", cl::desc("Sets the ASan destructor kind. The default is to use the value " "provided to the pass constructor"), cl::values(clEnumValN(AsanDtorKind::None, "none", "No destructors"), clEnumValN(AsanDtorKind::Global, "global", "Use global destructors")), cl::init(AsanDtorKind::Invalid), cl::Hidden)
static Twine genName(StringRef suffix)
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static uint64_t GetCtorAndDtorPriority(Triple &TargetTriple)
const char kAsanStackMallocNameTemplate[]
static cl::opt< bool > ClInstrumentByval("asan-instrument-byval", cl::desc("instrument byval call arguments"), cl::Hidden, cl::init(true))
const char kAsanInitName[]
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClRedzoneByvalArgs("asan-redzone-byval-args", cl::desc("Create redzones for byval " "arguments (extra copy " "required)"), cl::Hidden, cl::init(true))
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
static cl::opt< bool > ClOptimizeCallbacks("asan-optimize-callbacks", cl::desc("Optimize callbacks"), cl::Hidden, cl::init(false))
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(true))
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static cl::opt< int > ClShadowAddrSpace("asan-shadow-addr-space", cl::desc("Address space for pointers to the shadow map"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClInvalidPointerCmp("asan-detect-invalid-pointer-cmp", cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInvalidPointerSub("asan-detect-invalid-pointer-sub", cl::desc("Instrument - operations with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static cl::list< unsigned > ClAddrSpaces("asan-instrument-address-spaces", cl::desc("Only instrument variables in the specified address spaces."), cl::Hidden, cl::CommaSeparated, cl::callback([](const unsigned &AddrSpace) { SrcAddrSpaces.insert(AddrSpace);}))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
constexpr size_t kAccessSizeIndexShift
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
const char kAsanPoisonStackMemoryName[]
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isSupportedAddrspace(const Triple &TargetTriple, Value *Addr)
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static cl::opt< AsanDetectStackUseAfterReturnMode > ClUseAfterReturn("asan-use-after-return", cl::desc("Sets the mode of detection for stack-use-after-return."), cl::values(clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", "Never detect stack use after return."), clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, "runtime", "Detect stack use after return if " "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", "Always detect stack use after return.")), cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime))
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static const uintptr_t kCurrentStackFrameMagic
static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kPPC64_ShadowOffset64
static cl::opt< AsanCtorKind > ClConstructorKind("asan-constructor-kind", cl::desc("Sets the ASan constructor kind"), cl::values(clEnumValN(AsanCtorKind::None, "none", "No constructors"), clEnumValN(AsanCtorKind::Global, "global", "Use global constructors")), cl::init(AsanCtorKind::Global), cl::Hidden)
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
static const uint64_t kNetBSD_ShadowOffset64
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
static const uint64_t kWindowsShadowOffset32
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
static SmallSet< unsigned, 8 > SrcAddrSpaces
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const char kAsanReportErrorTemplate[]
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
static StringRef getAllocaName(AllocaInst *AI)
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
static const uintptr_t kRetiredStackFrameMagic
static cl::opt< bool > ClUseStackSafety("asan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"), cl::Optional)
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
static cl::opt< int > ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
static cl::opt< bool > ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, cl::init(false))
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool isPointerOperand(Value *I, User *U)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI AddressSanitizerPass(const AddressSanitizerOptions &Options, bool UseGlobalGC=true, bool UseOdrIndicator=true, AsanDtorKind DestructorKind=AsanDtorKind::Global, AsanCtorKind ConstructorKind=AsanCtorKind::Global)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - 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.
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
bool isInlineAsm() const
Check if this call is an inline asm statement.
static LLVM_ABI CallBase * addOperandBundle(CallBase *CB, uint32_t ID, OperandBundleDef OB, InsertPosition InsertPt=nullptr)
Create a clone of CB with operand bundle OB added.
bool doesNotReturn() const
Determine if the call cannot return.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
@ Largest
The linker will choose the largest COMDAT.
@ SameSize
The data referenced by the COMDAT must be the same size.
@ Any
The linker may choose any COMDAT.
@ NoDeduplicate
No deduplication is performed.
@ ExactMatch
The data referenced by the COMDAT must be the same.
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
ConstantArray - Constant Array Declarations.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI bool isValueValidForType(Type *Ty, uint64_t V)
This static method returns true if the type Ty is big enough to represent the value V.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
const BasicBlock & front() const
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
bool hasPersonalityFn() const
Check whether this function has a personality function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
const Constant * getAliasee() const
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
LLVM_ABI void copyMetadata(const GlobalObject *Src, unsigned Offset)
Copy metadata from Src, adjusting offsets by Offset.
LLVM_ABI void setComdat(Comdat *C)
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
VisibilityTypes getVisibility() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
ThreadLocalMode getThreadLocalMode() const
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
DLLStorageClassTypes getDLLStorageClass() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
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())
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Base class for instruction visitors.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
An instruction for reading from memory.
static Error ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
Parse the section specifier indicated by "Spec".
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
ArrayRef< MDOperand > operands() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This is the common base class for memset/memcpy/memmove.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
static MemoryEffectsBase otherMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
A Module instance is used to store all the information related to an LLVM module.
Evaluate the size and offset of an object pointed to by a Value* statically.
LLVM_ABI SizeOffsetAPInt compute(Value *V)
Pass interface - Implemented by all 'passes'.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Return a value (possibly void), from a function.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
bool stackAccessIsSafe(const Instruction &I) const
bool isSafe(const AllocaInst &AI) const
An instruction for storing to memory.
StringRef - 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
empty - Check if the string is empty.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
Triple - Helper class for working with autoconf configuration names.
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
bool isDriverKit() const
Is this an Apple DriverKit triple.
bool isBPF() const
Tests whether the target is eBPF.
bool isAndroid() const
Tests whether the target is Android.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isOSWindows() const
Tests whether the OS is Windows.
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isOSLinux() const
Tests whether the OS is Linux.
bool isMacOSX() const
Is this a Mac OS X triple.
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
bool isWatchOS() const
Is this an Apple watchOS triple.
bool isiOS() const
Is this an iOS triple.
bool isPS() const
Tests whether the target is the PS4 or PS5 platform.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
bool isOSHaiku() const
Tests whether the OS is Haiku.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class implements an extremely fast bulk output stream that can only output to a stream.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void getInterestingMemoryOperands(Module &M, Instruction *I, SmallVectorImpl< InterestingMemoryOperand > &Interesting)
Get all the memory operands from the instruction that needs to be instrumented.
void instrumentAddress(Module &M, IRBuilder<> &IRB, Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, Align Alignment, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, bool Recover, int AsanScale, int AsanOffset)
Instrument the memory operand Addr.
uint64_t getRedzoneSizeForGlobal(int AsanScale, uint64_t SizeInBytes)
Given SizeInBytes of the Value to be instrunmented, Returns the redzone size corresponding to it.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
cb< typename detail::callback_traits< F >::result_type, typename detail::callback_traits< F >::arg_type > callback(F CB)
uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
Context & getContext() const
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
FunctionAddr VTableAddr Value
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
LLVM_ABI GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, Twine NamePrefix="")
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
LLVM_ABI Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
AsanDetectStackUseAfterReturnMode
Mode of ASan detect stack use after return.
@ Always
Always detect stack use after return.
@ Never
Never detect stack use after return.
@ Runtime
Detect stack use after return if not disabled runtime with (ASAN_OPTIONS=detect_stack_use_after_retur...
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
LLVM_ABI SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytes(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
AsanDtorKind
Types of ASan module destructors supported.
@ Invalid
Not a valid destructor Kind.
@ Global
Append to llvm.global_dtors.
@ None
Do not emit any destructors for ASan.
LLVM_ABI ASanStackFrameLayout ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, uint64_t Granularity, uint64_t MinHeaderSize)
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
OperandBundleDefT< Value * > OperandBundleDef
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
static const int kAsanStackUseAfterReturnMagic
LLVM_ABI void setGlobalVariableLargeSection(const Triple &TargetTriple, GlobalVariable &GV)
void removeASanIncompatibleFnAttributes(Function &F, bool ReadsArgMem)
Remove memory attributes that are incompatible with the instrumentation added by AddressSanitizer and...
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isModAndRefSet(const ModRefInfo MRI)
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
TinyPtrVector< BasicBlock * > ColorVector
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
AsanCtorKind
Types of ASan module constructors supported.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
std::string itostr(int64_t X)
LLVM_ABI void SplitBlockAndInsertForEachLane(ElementCount EC, Type *IndexTy, BasicBlock::iterator InsertBefore, std::function< void(IRBuilderBase &, Value *)> Func)
Utility function for performing a given action on each lane of a vector with EC elements.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset)
Replaces dbg.declare record when the address it describes is replaced with a new value.
LLVM_ABI ASanAccessInfo(int32_t Packed)
const uint8_t AccessSizeIndex
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Information about a load/store intrinsic defined by the target.
SmallVector< InterestingMemoryOperand, 1 > InterestingOperands
A CRTP mix-in to automatically provide informational APIs needed for passes.
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.