98#define DEBUG_TYPE "asan"
104 std::numeric_limits<uint64_t>::max();
145 "__asan_unregister_image_globals";
158 "__asan_stack_malloc_always_";
172 "__asan_option_detect_stack_use_after_return";
175 "__asan_shadow_memory_dynamic_address";
201 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
206 cl::desc(
"Enable recovery mode (continue-after-error)."),
210 "asan-guard-against-version-mismatch",
216 cl::desc(
"instrument read instructions"),
220 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
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)
620 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
621 !IsRISCV64 && !IsLoongArch64 &&
622 !(Mapping.Offset & (Mapping.Offset - 1)) &&
624 Mapping.InGlobal =
ClWithIfunc && IsAndroid && IsArmOrThumb;
630 bool IsKasan, uint64_t *ShadowBase,
631 int *MappingScale,
bool *OrShadowOffset) {
633 *ShadowBase = Mapping.Offset;
634 *MappingScale = Mapping.Scale;
635 *OrShadowOffset = Mapping.OrShadowOffset;
656 if (!
F.getMemoryEffects()
658 .doesNotAccessMemory() &&
660 F.setMemoryEffects(
F.getMemoryEffects() |
668 F.setMemoryEffects(
F.getMemoryEffects() |
673 if (
A.hasAttribute(Attribute::WriteOnly)) {
674 A.removeAttr(Attribute::WriteOnly);
682 F.addFnAttr(Attribute::NoBuiltin);
703 return std::max(32U, 1U << MappingScale);
719class AsanFunctionInserter {
721 AsanFunctionInserter(
Module &M) :
M(
M) {}
723 template <
typename... ArgTypes>
724 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
725 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
738class RuntimeCallInserter {
740 bool TrackInsertedCalls =
false;
744 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
746 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
747 if (isScopedEHPersonality(Personality))
748 TrackInsertedCalls = true;
752 ~RuntimeCallInserter() {
753 if (InsertedCalls.
empty())
755 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
757 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
758 for (CallInst *CI : InsertedCalls) {
760 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
762 "Instruction doesn't belong to the expected Function!");
770 if (Colors.
size() != 1) {
772 "Instruction's BasicBlock is not monochromatic");
779 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
783 OB, CI->getIterator());
784 NewCall->copyMetadata(*CI);
785 CI->replaceAllUsesWith(NewCall);
786 CI->eraseFromParent();
791 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
793 const Twine &
Name =
"") {
796 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
797 if (TrackInsertedCalls)
798 InsertedCalls.push_back(Inst);
804struct AddressSanitizer {
805 AddressSanitizer(
Module &M,
const StackSafetyGlobalInfo *SSGI,
806 int InstrumentationWithCallsThreshold,
807 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
808 bool Recover =
false,
bool UseAfterScope =
false,
810 AsanDetectStackUseAfterReturnMode::Runtime)
819 InstrumentationWithCallsThreshold(
822 : InstrumentationWithCallsThreshold),
825 : MaxInlinePoisoningSize) {
826 C = &(
M.getContext());
827 DL = &
M.getDataLayout();
828 LongSize =
M.getDataLayout().getPointerSizeInBits();
829 IntptrTy = Type::getIntNTy(*
C, LongSize);
830 PtrTy = PointerType::getUnqual(*
C);
831 Int32Ty = Type::getInt32Ty(*
C);
832 TargetTriple =
M.getTargetTriple();
836 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
844 bool isInterestingAlloca(
const AllocaInst &AI);
846 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
848 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
849 const TargetTransformInfo *
TTI);
851 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
852 InterestingMemoryOperand &O,
bool UseCalls,
853 const DataLayout &
DL, RuntimeCallInserter &RTCI);
854 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
855 RuntimeCallInserter &RTCI);
857 Value *Addr, MaybeAlign Alignment,
858 uint32_t TypeStoreSize,
bool IsWrite,
859 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
860 RuntimeCallInserter &RTCI);
861 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
862 Instruction *InsertBefore,
Value *Addr,
863 uint32_t TypeStoreSize,
bool IsWrite,
864 Value *SizeArgument);
867 void instrumentUnusualSizeOrAlignment(Instruction *
I,
868 Instruction *InsertBefore,
Value *Addr,
869 TypeSize TypeStoreSize,
bool IsWrite,
870 Value *SizeArgument,
bool UseCalls,
872 RuntimeCallInserter &RTCI);
873 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
876 MaybeAlign Alignment,
unsigned Granularity,
877 Type *OpType,
bool IsWrite,
878 Value *SizeArgument,
bool UseCalls,
879 uint32_t Exp, RuntimeCallInserter &RTCI);
881 Value *ShadowValue, uint32_t TypeStoreSize);
883 bool IsWrite,
size_t AccessSizeIndex,
884 Value *SizeArgument, uint32_t Exp,
885 RuntimeCallInserter &RTCI);
886 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
888 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
889 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
890 const TargetTransformInfo *
TTI);
891 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
892 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
893 void markEscapedLocalAllocas(
Function &
F);
894 void markCatchParametersAsUninteresting(
Function &
F);
897 friend struct FunctionStackPoisoner;
899 void initializeCallbacks(
const TargetLibraryInfo *TLI);
901 bool LooksLikeCodeInBug11395(Instruction *
I);
902 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
903 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
904 TypeSize TypeStoreSize)
const;
907 struct FunctionStateRAII {
908 AddressSanitizer *
Pass;
910 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
912 "last pass forgot to clear cache");
916 ~FunctionStateRAII() {
917 Pass->LocalDynamicShadow =
nullptr;
918 Pass->ProcessedAllocas.clear();
923 AsanFunctionInserter Inserter;
925 const DataLayout *
DL;
935 ShadowMapping Mapping;
936 FunctionCallee AsanHandleNoReturnFunc;
937 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
945 FunctionCallee AsanErrorCallbackSized[2][2];
946 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
948 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
949 Value *LocalDynamicShadow =
nullptr;
950 const StackSafetyGlobalInfo *SSGI;
951 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
953 FunctionCallee AMDGPUAddressShared;
954 FunctionCallee AMDGPUAddressPrivate;
955 int InstrumentationWithCallsThreshold;
956 uint32_t MaxInlinePoisoningSize;
959class ModuleAddressSanitizer {
961 ModuleAddressSanitizer(
Module &M,
bool InsertVersionCheck,
962 bool CompileKernel =
false,
bool Recover =
false,
963 bool UseGlobalsGC =
true,
bool UseOdrIndicator =
true,
971 : InsertVersionCheck),
973 UseGlobalsGC(UseGlobalsGC &&
ClUseGlobalsGC && !this->CompileKernel),
988 UseCtorComdat(UseGlobalsGC &&
ClWithComdat && !this->CompileKernel),
989 DestructorKind(DestructorKind),
993 C = &(
M.getContext());
994 int LongSize =
M.getDataLayout().getPointerSizeInBits();
995 IntptrTy = Type::getIntNTy(*
C, LongSize);
996 PtrTy = PointerType::getUnqual(*
C);
997 TargetTriple =
M.getTargetTriple();
1002 assert(this->DestructorKind != AsanDtorKind::Invalid);
1005 bool instrumentModule();
1008 void initializeCallbacks();
1010 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
1017 const std::string &UniqueModuleId);
1022 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
1026 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
1027 StringRef OriginalName);
1028 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
1029 StringRef InternalSuffix);
1032 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
1033 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
1034 bool ShouldUseMachOGlobalsSection()
const;
1035 StringRef getGlobalMetadataSection()
const;
1036 void poisonOneInitializer(
Function &GlobalInit);
1037 void createInitializerPoisonCalls();
1038 uint64_t getMinRedzoneSizeForGlobal()
const {
1042 int GetAsanVersion()
const;
1043 GlobalVariable *getOrCreateModuleName();
1046 AsanFunctionInserter Inserter;
1048 bool InsertVersionCheck;
1051 bool UsePrivateAlias;
1052 bool UseOdrIndicator;
1059 Triple TargetTriple;
1060 ShadowMapping Mapping;
1061 FunctionCallee AsanPoisonGlobals;
1062 FunctionCallee AsanUnpoisonGlobals;
1063 FunctionCallee AsanRegisterGlobals;
1064 FunctionCallee AsanUnregisterGlobals;
1065 FunctionCallee AsanRegisterImageGlobals;
1066 FunctionCallee AsanUnregisterImageGlobals;
1067 FunctionCallee AsanRegisterElfGlobals;
1068 FunctionCallee AsanUnregisterElfGlobals;
1070 Function *AsanCtorFunction =
nullptr;
1071 Function *AsanDtorFunction =
nullptr;
1072 GlobalVariable *ModuleName =
nullptr;
1084struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
1086 AddressSanitizer &ASan;
1087 RuntimeCallInserter &RTCI;
1092 ShadowMapping Mapping;
1096 SmallVector<Instruction *, 8> RetVec;
1100 FunctionCallee AsanSetShadowFunc[0x100] = {};
1101 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
1102 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
1105 struct AllocaPoisonCall {
1106 IntrinsicInst *InsBefore;
1116 AllocaInst *DynamicAllocaLayout =
nullptr;
1117 IntrinsicInst *LocalEscapeCall =
nullptr;
1119 bool HasInlineAsm =
false;
1120 bool HasReturnsTwiceCall =
false;
1123 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
1124 RuntimeCallInserter &RTCI)
1125 :
F(
F), ASan(ASan), RTCI(RTCI),
1127 IntptrTy(ASan.IntptrTy),
1129 Mapping(ASan.Mapping),
1137 copyArgsPassedByValToAllocas();
1142 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
1144 initializeCallbacks(*
F.getParent());
1146 processDynamicAllocas();
1147 processStaticAllocas();
1158 void copyArgsPassedByValToAllocas();
1163 void processStaticAllocas();
1164 void processDynamicAllocas();
1166 void createDynamicAllocasInitStorage();
1171 void visitReturnInst(ReturnInst &RI) {
1172 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
1179 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
1182 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
1184 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
1185 Value *SavedStack) {
1194 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
1200 RTCI.createRuntimeCall(
1201 IRB, AsanAllocasUnpoisonFunc,
1202 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
1206 void unpoisonDynamicAllocas() {
1207 for (Instruction *Ret : RetVec)
1208 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
1210 for (Instruction *StackRestoreInst : StackRestoreVec)
1211 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
1212 StackRestoreInst->getOperand(0));
1225 void handleDynamicAllocaCall(AllocaInst *AI);
1228 void visitAllocaInst(AllocaInst &AI) {
1230 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
1234 if (AllocaVec.
empty())
1250 void visitIntrinsicInst(IntrinsicInst &
II) {
1252 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
1253 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
1254 if (!ASan.UseAfterScope)
1256 if (!
II.isLifetimeStartOrEnd())
1261 if (!AI || !ASan.isInterestingAlloca(*AI))
1271 bool DoPoison = (
ID == Intrinsic::lifetime_end);
1272 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
1274 StaticAllocaPoisonCallVec.
push_back(APC);
1276 DynamicAllocaPoisonCallVec.
push_back(APC);
1279 void visitCallBase(CallBase &CB) {
1281 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1282 HasReturnsTwiceCall |= CI->canReturnTwice();
1287 void initializeCallbacks(
Module &M);
1292 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1294 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1297 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1298 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1303 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1306 Instruction *ThenTerm,
Value *ValueIfFalse);
1313 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1314 OS, MapClassName2PassName);
1316 if (Options.CompileKernel)
1318 if (Options.UseAfterScope)
1319 OS <<
"use-after-scope";
1327 : Options(Options), UseGlobalGC(UseGlobalGC),
1328 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1329 ConstructorKind(ConstructorKind) {}
1338 ModuleAddressSanitizer ModuleSanitizer(
1339 M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
1340 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
1352 if (
F.getName().starts_with(
"__asan_"))
1354 if (
F.isPresplitCoroutine())
1356 AddressSanitizer FunctionSanitizer(
1357 M, SSGI, Options.InstrumentationWithCallsThreshold,
1358 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1359 Options.UseAfterScope, Options.UseAfterReturn);
1362 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1364 Modified |= ModuleSanitizer.instrumentModule();
1385 if (
G->getName().starts_with(
"llvm.") ||
1387 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1389 G->getName().starts_with(
"__llvm_rtti_proxy"))
1405 if (AddrSpace == 3 || AddrSpace == 5)
1420 return AddrSpace == 0;
1424 if (TargetTriple.isOSDarwin() &&
1428 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1431 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1432 if (Mapping.Offset == 0)
return Shadow;
1435 if (LocalDynamicShadow)
1436 ShadowBase = LocalDynamicShadow;
1438 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1439 if (Mapping.OrShadowOffset)
1440 return IRB.
CreateOr(Shadow, ShadowBase);
1442 return IRB.
CreateAdd(Shadow, ShadowBase);
1447 RuntimeCallInserter &RTCI) {
1450 RTCI.createRuntimeCall(
1456 RTCI.createRuntimeCall(
1462 MI->eraseFromParent();
1466bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1467 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1470 return It->getSecond();
1472 bool IsInteresting =
1483 !(SSGI && SSGI->
isSafe(AI)));
1485 It->second = IsInteresting;
1486 return IsInteresting;
1516void AddressSanitizer::getInterestingMemoryOperands(
1520 if (LocalDynamicShadow ==
I)
1526 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1527 LI->getType(), LI->getAlign());
1532 SI->getValueOperand()->getType(),
SI->getAlign());
1536 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1537 RMW->getValOperand()->getType(), std::nullopt);
1541 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1542 XCHG->getCompareOperand()->getType(),
1545 switch (CI->getIntrinsicID()) {
1546 case Intrinsic::masked_load:
1547 case Intrinsic::masked_store:
1548 case Intrinsic::masked_gather:
1549 case Intrinsic::masked_scatter: {
1550 bool IsWrite = CI->getType()->isVoidTy();
1552 unsigned OpOffset = IsWrite ? 1 : 0;
1556 auto BasePtr = CI->getOperand(OpOffset);
1557 if (ignoreAccess(
I, BasePtr))
1559 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1561 Value *
Mask = CI->getOperand(1 + OpOffset);
1562 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1565 case Intrinsic::masked_expandload:
1566 case Intrinsic::masked_compressstore: {
1567 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1568 unsigned OpOffset = IsWrite ? 1 : 0;
1571 auto BasePtr = CI->getOperand(OpOffset);
1572 if (ignoreAccess(
I, BasePtr))
1575 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1578 Value *
Mask = CI->getOperand(1 + OpOffset);
1581 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1582 Value *EVL =
IB.CreateAddReduce(ExtMask);
1583 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1584 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1588 case Intrinsic::vp_load:
1589 case Intrinsic::vp_store:
1590 case Intrinsic::experimental_vp_strided_load:
1591 case Intrinsic::experimental_vp_strided_store: {
1593 unsigned IID = CI->getIntrinsicID();
1594 bool IsWrite = CI->getType()->isVoidTy();
1597 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1598 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1600 Value *Stride =
nullptr;
1601 if (IID == Intrinsic::experimental_vp_strided_store ||
1602 IID == Intrinsic::experimental_vp_strided_load) {
1603 Stride = VPI->getOperand(PtrOpNo + 1);
1607 unsigned PointerAlign =
Alignment.valueOrOne().value();
1612 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1613 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1617 case Intrinsic::vp_gather:
1618 case Intrinsic::vp_scatter: {
1620 unsigned IID = CI->getIntrinsicID();
1621 bool IsWrite = IID == Intrinsic::vp_scatter;
1624 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1625 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1627 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1628 VPI->getMaskParam(),
1629 VPI->getVectorLengthParam());
1635 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1639 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1641 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1643 Type *Ty = CI->getParamByValType(ArgNo);
1659 if (!Cmp->isRelational())
1673 if (BO->getOpcode() != Instruction::Sub)
1686 if (!
G->hasInitializer())
1689 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1696 Type *Ty = V->getType();
1697 if (Ty->isPtrOrPtrVectorTy())
1703bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1705 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1720 "invalid vector pointer pair instrumentation operands");
1721 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1722 Index != NumElements; ++Index) {
1723 Value *ScalarParam[2] = {
1730 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1737 RTCI.createRuntimeCall(IRB,
F, Param);
1744 TypeSize TypeStoreSize,
bool IsWrite,
1745 Value *SizeArgument,
bool UseCalls,
1746 uint32_t Exp, RuntimeCallInserter &RTCI) {
1751 switch (FixedSize) {
1757 if (!Alignment || *Alignment >= Granularity ||
1758 *Alignment >= FixedSize / 8)
1759 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1760 FixedSize, IsWrite,
nullptr, UseCalls,
1764 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1765 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1768void AddressSanitizer::instrumentMaskedLoadOrStore(
1771 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1772 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1773 RuntimeCallInserter &RTCI) {
1775 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1776 auto Zero = ConstantInt::get(IntptrTy, 0);
1784 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1786 IB.SetInsertPoint(LoopInsertBefore);
1788 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1791 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1792 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1794 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1799 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1803 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1804 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1805 if (MaskElemC->isZero())
1811 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1812 MaskElem, &*IRB.GetInsertPoint(), false);
1813 IRB.SetInsertPoint(ThenTerm);
1816 Value *InstrumentedAddress;
1819 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1820 "Expected vector of pointer.");
1821 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1822 }
else if (Stride) {
1829 Alignment, Granularity, ElemTypeSize, IsWrite,
1830 SizeArgument, UseCalls, Exp, RTCI);
1837 RuntimeCallInserter &RTCI) {
1838 Value *Addr =
O.getPtr();
1858 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1859 NumOptimizedAccessesToGlobalVar++;
1867 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1868 NumOptimizedAccessesToStackVar++;
1874 NumInstrumentedWrites++;
1876 NumInstrumentedReads++;
1878 if (
O.MaybeByteOffset) {
1883 if (TargetTriple.isRISCV()) {
1888 static_cast<unsigned>(LongSize)) {
1897 unsigned Granularity = 1 << Mapping.Scale;
1899 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1900 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1901 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1902 UseCalls, Exp, RTCI);
1905 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1906 UseCalls, Exp, RTCI);
1911 Value *Addr,
bool IsWrite,
1912 size_t AccessSizeIndex,
1913 Value *SizeArgument,
1915 RuntimeCallInserter &RTCI) {
1921 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1922 {Addr, SizeArgument});
1924 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1925 {Addr, SizeArgument, ExpVal});
1928 Call = RTCI.createRuntimeCall(
1929 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1931 Call = RTCI.createRuntimeCall(
1932 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1941 uint32_t TypeStoreSize) {
1942 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1944 Value *LastAccessedByte =
1945 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1947 if (TypeStoreSize / 8 > 1)
1949 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1952 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1957Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1959 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1966 return InsertBefore;
1971 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1973 Value *AddrSpaceZeroLanding =
1976 return InsertBefore;
1991 Trm->getParent()->setName(
"asan.report");
2002void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
2005 uint32_t TypeStoreSize,
bool IsWrite,
2006 Value *SizeArgument,
bool UseCalls,
2008 RuntimeCallInserter &RTCI) {
2009 if (TargetTriple.isAMDGPU()) {
2010 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
2011 TypeStoreSize, IsWrite, SizeArgument);
2020 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
2023 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
2030 RTCI.createRuntimeCall(
2031 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
2033 RTCI.createRuntimeCall(
2034 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
2035 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
2042 Value *ShadowPtr = memToShadow(AddrLong, IRB);
2044 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
2049 size_t Granularity = 1ULL << Mapping.Scale;
2052 bool GenSlowPath = (
ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
2054 if (TargetTriple.isAMDGCN()) {
2056 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2059 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2060 }
else if (GenSlowPath) {
2067 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2082 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2091void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2093 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
2094 uint32_t Exp, RuntimeCallInserter &RTCI) {
2102 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2105 RTCI.createRuntimeCall(
2106 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2120void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
2126 Value *ModuleNameAddr =
2134 for (
auto &BB : GlobalInit)
2146void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2166 poisonOneInitializer(*
F);
2172ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
2177 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
2189bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
2190 Type *Ty =
G->getValueType();
2193 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
2195 if (!Ty->
isSized())
return false;
2196 if (!
G->hasInitializer())
return false;
2203 if (
G->isThreadLocal())
return false;
2205 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
2211 if (!TargetTriple.isOSBinFormatCOFF()) {
2212 if (!
G->hasExactDefinition() ||
G->hasComdat())
2216 if (
G->isInterposable())
2220 if (
G->hasAvailableExternallyLinkage())
2227 switch (
C->getSelectionKind()) {
2238 if (
G->hasSection()) {
2248 if (Section ==
"llvm.metadata")
return false;
2255 if (
Section.starts_with(
".preinit_array") ||
2256 Section.starts_with(
".init_array") ||
2257 Section.starts_with(
".fini_array")) {
2263 if (TargetTriple.isOSBinFormatELF()) {
2277 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2278 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2283 if (TargetTriple.isOSBinFormatMachO()) {
2285 unsigned TAA = 0, StubSize = 0;
2288 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2293 if (ParsedSegment ==
"__OBJC" ||
2294 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2306 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2319 if (CompileKernel) {
2322 if (
G->getName().starts_with(
"__"))
2332bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2333 if (!TargetTriple.isOSBinFormatMachO())
2336 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2338 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2340 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2342 if (TargetTriple.isDriverKit())
2344 if (TargetTriple.isXROS())
2350StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2351 switch (TargetTriple.getObjectFormat()) {
2361 "ModuleAddressSanitizer not implemented for object file format");
2368void ModuleAddressSanitizer::initializeCallbacks() {
2374 AsanUnpoisonGlobals =
2378 AsanRegisterGlobals = Inserter.insertFunction(
2380 AsanUnregisterGlobals = Inserter.insertFunction(
2385 AsanRegisterImageGlobals = Inserter.insertFunction(
2387 AsanUnregisterImageGlobals = Inserter.insertFunction(
2390 AsanRegisterElfGlobals =
2392 IntptrTy, IntptrTy, IntptrTy);
2393 AsanUnregisterElfGlobals =
2395 IntptrTy, IntptrTy, IntptrTy);
2400void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2405 if (!
G->hasName()) {
2409 G->setName(
genName(
"anon_global"));
2412 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2413 std::string
Name = std::string(
G->getName());
2414 Name += InternalSuffix;
2415 C =
M.getOrInsertComdat(Name);
2417 C =
M.getOrInsertComdat(
G->getName());
2423 if (TargetTriple.isOSBinFormatCOFF()) {
2425 if (
G->hasPrivateLinkage())
2438ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2440 auto Linkage = TargetTriple.isOSBinFormatMachO()
2446 Metadata->setSection(getGlobalMetadataSection());
2453Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2457 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2465void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2469 auto &
DL =
M.getDataLayout();
2472 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2473 Constant *Initializer = MetadataInitializers[i];
2477 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2483 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2485 "global metadata will not be padded appropriately");
2488 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2493 if (!MetadataGlobals.empty())
2497void ModuleAddressSanitizer::instrumentGlobalsELF(
2500 const std::string &UniqueModuleId) {
2507 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2510 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2513 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2515 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2518 if (UseComdatForGlobalsGC)
2519 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2524 if (!MetadataGlobals.empty())
2541 "__start_" + getGlobalMetadataSection());
2545 "__stop_" + getGlobalMetadataSection());
2559 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2566void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2577 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2578 Constant *Initializer = MetadataInitializers[i];
2584 auto LivenessBinder =
2589 Twine(
"__asan_binder_") +
G->getName());
2590 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2591 LivenessGlobals[i] = Liveness;
2598 if (!LivenessGlobals.empty())
2620 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2625void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2629 unsigned N = ExtendedGlobals.
size();
2639 if (Mapping.Scale > 3)
2640 AllGlobals->setAlignment(
Align(1ULL << Mapping.Scale));
2645 ConstantInt::get(IntptrTy,
N)});
2651 IrbDtor.CreateCall(AsanUnregisterGlobals,
2653 ConstantInt::get(IntptrTy,
N)});
2662void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2667 if (CompileKernel) {
2668 for (
auto &GA :
M.aliases()) {
2670 AliasedGlobalExclusions.
insert(GV);
2675 for (
auto &
G :
M.globals()) {
2676 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2680 size_t n = GlobalsToChange.
size();
2681 auto &
DL =
M.getDataLayout();
2695 IntptrTy, IntptrTy, IntptrTy);
2699 for (
size_t i = 0; i < n; i++) {
2703 if (
G->hasSanitizerMetadata())
2704 MD =
G->getSanitizerMetadata();
2709 std::string NameForGlobal =
G->getName().str();
2714 Type *Ty =
G->getValueType();
2715 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2728 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2729 G->getThreadLocalMode(),
G->getAddressSpace());
2739 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2742 if (Seq && Seq->isCString())
2743 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2750 G->replaceAllUsesWith(NewGlobal);
2752 G->eraseFromParent();
2753 NewGlobals[i] = NewGlobal;
2758 bool CanUsePrivateAliases =
2759 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2760 TargetTriple.isOSBinFormatWasm();
2761 if (CanUsePrivateAliases && UsePrivateAlias) {
2764 InstrumentedGlobal =
2771 }
else if (UseOdrIndicator) {
2774 auto *ODRIndicatorSym =
2783 ODRIndicatorSym->setAlignment(
Align(1));
2790 ConstantInt::get(IntptrTy, SizeInBytes),
2791 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2794 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2799 Initializers[i] = Initializer;
2805 for (
size_t i = 0; i < n; i++) {
2807 if (
G->getName().empty())
continue;
2812 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2819 }
else if (n == 0) {
2822 *CtorComdat = TargetTriple.isOSBinFormatELF();
2824 *CtorComdat =
false;
2825 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2826 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2827 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2828 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2830 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2836 createInitializerPoisonCalls();
2842ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2843 constexpr uint64_t kMaxRZ = 1 << 18;
2844 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2847 if (SizeInBytes <= MinRZ / 2) {
2851 RZ = MinRZ - SizeInBytes;
2854 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2857 if (SizeInBytes % MinRZ)
2858 RZ += MinRZ - (SizeInBytes % MinRZ);
2861 assert((RZ + SizeInBytes) % MinRZ == 0);
2866int ModuleAddressSanitizer::GetAsanVersion()
const {
2867 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2868 bool isAndroid =
M.getTargetTriple().isAndroid();
2872 Version += (LongSize == 32 && isAndroid);
2887bool ModuleAddressSanitizer::instrumentModule() {
2888 initializeCallbacks();
2896 if (CompileKernel) {
2901 std::string AsanVersion = std::to_string(GetAsanVersion());
2902 std::string VersionCheckName =
2904 std::tie(AsanCtorFunction, std::ignore) =
2907 {}, VersionCheckName);
2911 bool CtorComdat =
true;
2914 if (AsanCtorFunction) {
2915 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2916 instrumentGlobals(IRB, &CtorComdat);
2919 instrumentGlobals(IRB, &CtorComdat);
2928 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2929 if (AsanCtorFunction) {
2933 if (AsanDtorFunction) {
2938 if (AsanCtorFunction)
2940 if (AsanDtorFunction)
2951 for (
int Exp = 0;
Exp < 2;
Exp++) {
2952 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2953 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2954 const std::string ExpStr =
Exp ?
"exp_" :
"";
2955 const std::string EndingStr = Recover ?
"_noabort" :
"";
2965 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2966 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2967 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2970 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2974 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2975 Inserter.insertFunction(
2980 AccessSizeIndex++) {
2981 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2982 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2983 Inserter.insertFunction(
2987 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2988 Inserter.insertFunction(
2995 const std::string MemIntrinCallbackPrefix =
2999 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
3000 PtrTy, PtrTy, PtrTy, IntptrTy);
3001 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
3002 PtrTy, PtrTy, PtrTy, IntptrTy);
3004 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
3009 AsanHandleNoReturnFunc =
3012 AsanPtrCmpFunction =
3014 AsanPtrSubFunction =
3016 if (Mapping.InGlobal)
3017 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
3020 AMDGPUAddressShared =
3026bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
3034 if (
F.getName().contains(
" load]")) {
3044bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
3050 if (Mapping.InGlobal) {
3058 LocalDynamicShadow =
3059 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
3061 LocalDynamicShadow =
3065 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
3067 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
3072void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
3077 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
3081 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
3087 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
3089 for (
Value *Arg :
II->args()) {
3092 "non-static alloca arg to localescape");
3093 ProcessedAllocas[AI] =
false;
3102void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
3108 for (
Value *Operand : CatchPad->arg_operands())
3110 ProcessedAllocas[AI] =
false;
3116bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
3117 bool ShouldInstrument =
3121 return !ShouldInstrument;
3124bool AddressSanitizer::instrumentFunction(
Function &
F,
3127 bool FunctionModified =
false;
3130 if (
F.hasFnAttribute(Attribute::Naked))
3131 return FunctionModified;
3136 if (maybeInsertAsanInitAtFunctionEntry(
F))
3137 FunctionModified =
true;
3140 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
3142 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3143 return FunctionModified;
3147 initializeCallbacks(TLI);
3149 FunctionStateRAII CleanupObj(
this);
3151 RuntimeCallInserter RTCI(
F);
3153 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
3157 markEscapedLocalAllocas(
F);
3159 if (TargetTriple.isOSWindows())
3160 markCatchParametersAsUninteresting(
F);
3172 for (
auto &BB :
F) {
3174 TempsToInstrument.
clear();
3175 int NumInsnsPerBB = 0;
3176 for (
auto &Inst : BB) {
3177 if (LooksLikeCodeInBug11395(&Inst))
return false;
3184 if (!InterestingOperands.
empty()) {
3185 for (
auto &Operand : InterestingOperands) {
3187 Value *Ptr = Operand.getPtr();
3191 if (Operand.MaybeMask) {
3192 if (TempsToInstrument.
count(Ptr))
3195 if (!TempsToInstrument.
insert(Ptr).second)
3199 OperandsToInstrument.
push_back(Operand);
3206 PointerComparisonsOrSubtracts.
push_back(&Inst);
3214 TempsToInstrument.
clear();
3225 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3226 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
3227 (
unsigned)InstrumentationWithCallsThreshold);
3232 int NumInstrumented = 0;
3233 for (
auto &Operand : OperandsToInstrument) {
3234 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3235 instrumentMop(ObjSizeVis, Operand, UseCalls,
3236 F.getDataLayout(), RTCI);
3237 FunctionModified =
true;
3239 for (
auto *Inst : IntrinToInstrument) {
3240 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3241 instrumentMemIntrinsic(Inst, RTCI);
3242 FunctionModified =
true;
3245 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3246 bool ChangedStack = FSP.runOnFunction();
3250 for (
auto *CI : NoReturnCalls) {
3252 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3255 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3256 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3259 if (ChangedStack || !NoReturnCalls.empty())
3260 FunctionModified =
true;
3262 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3265 return FunctionModified;
3271bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3272 if (LongSize != 32)
return false;
3281void FunctionStackPoisoner::initializeCallbacks(
Module &) {
3285 const char *MallocNameTemplate =
3290 std::string Suffix =
itostr(Index);
3291 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3292 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3293 AsanStackFreeFunc[
Index] =
3298 if (ASan.UseAfterScope) {
3299 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3301 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3305 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3306 0xf3, 0xf5, 0xf8}) {
3307 std::ostringstream
Name;
3309 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3310 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3314 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3316 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3322 size_t Begin,
size_t End,
3324 Value *ShadowBase) {
3328 const size_t LargestStoreSizeInBytes =
3329 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3331 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3337 for (
size_t i = Begin; i < End;) {
3338 if (!ShadowMask[i]) {
3344 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3346 while (StoreSizeInBytes > End - i)
3347 StoreSizeInBytes /= 2;
3350 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3351 while (j <= StoreSizeInBytes / 2)
3352 StoreSizeInBytes /= 2;
3356 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3358 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3360 Val = (Val << 8) | ShadowBytes[i + j];
3363 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3369 i += StoreSizeInBytes;
3376 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3381 size_t Begin,
size_t End,
3384 size_t Done = Begin;
3385 for (
size_t i = Begin, j = Begin + 1; i < End; i =
j++) {
3386 if (!ShadowMask[i]) {
3390 uint8_t Val = ShadowBytes[i];
3391 if (!AsanSetShadowFunc[Val])
3395 for (;
j < End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3398 if (j - i >= ASan.MaxInlinePoisoningSize) {
3399 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3400 RTCI.createRuntimeCall(
3401 IRB, AsanSetShadowFunc[Val],
3402 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3403 ConstantInt::get(IntptrTy, j - i)});
3408 copyToShadowInline(ShadowMask, ShadowBytes,
Done, End, IRB, ShadowBase);
3416 for (
int i = 0;; i++, MaxSize *= 2)
3417 if (LocalStackSize <= MaxSize)
return i;
3421void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3423 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3431 if (Arg.hasByValAttr()) {
3432 Type *Ty = Arg.getParamByValType();
3434 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3438 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3441 Arg.replaceAllUsesWith(AI);
3443 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3444 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3452 Value *ValueIfFalse) {
3455 PHI->addIncoming(ValueIfFalse, CondBlock);
3457 PHI->addIncoming(ValueIfTrue, ThenBlock);
3461Value *FunctionStackPoisoner::createAllocaForLayout(
3470 nullptr,
"MyAlloca");
3479void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3482 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3487void FunctionStackPoisoner::processDynamicAllocas() {
3494 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3497 assert(ASan.isInterestingAlloca(*APC.AI));
3498 assert(!APC.AI->isStaticAlloca());
3501 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3508 createDynamicAllocasInitStorage();
3509 for (
auto &AI : DynamicAllocaVec)
3510 handleDynamicAllocaCall(AI);
3511 unpoisonDynamicAllocas();
3523 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3540 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3545 bool IsArgInitViaCast =
3550 Val == It->getPrevNode();
3551 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3555 if (IsArgInitViaCast)
3570 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3573 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3577 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3580 auto MetadataString =
3582 if (MetadataString->getString() ==
"alloca_name_altered")
3591void FunctionStackPoisoner::processStaticAllocas() {
3592 if (AllocaVec.
empty()) {
3597 int StackMallocIdx = -1;
3599 if (
auto SP =
F.getSubprogram())
3600 EntryDebugLocation =
3609 auto InsBeforeB = InsBefore->
getParent();
3610 assert(InsBeforeB == &
F.getEntryBlock());
3611 for (
auto *AI : StaticAllocasToMoveUp)
3622 ArgInitInst->moveBefore(InsBefore->
getIterator());
3625 if (LocalEscapeCall)
3633 ASan.getAllocaSizeInBytes(*AI),
3644 uint64_t Granularity = 1ULL << Mapping.Scale;
3645 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3651 for (
auto &
Desc : SVD)
3655 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3658 assert(ASan.isInterestingAlloca(*APC.AI));
3659 assert(APC.AI->isStaticAlloca());
3664 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3665 if (LifetimeLoc->getFile() == FnLoc->getFile())
3666 if (
unsigned Line = LifetimeLoc->getLine())
3667 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3673 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3675 bool DoStackMalloc =
3685 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3686 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3688 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3689 Value *StaticAlloca =
3690 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3692 Value *FakeStackPtr;
3693 Value *FakeStackInt;
3694 Value *LocalStackBase;
3695 Value *LocalStackBaseAlloca;
3698 if (DoStackMalloc) {
3699 LocalStackBaseAlloca =
3700 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3707 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3717 Value *FakeStackValue =
3718 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3719 ConstantInt::get(IntptrTy, LocalStackSize));
3721 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3722 Term, ConstantInt::get(IntptrTy, 0));
3730 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3731 ConstantInt::get(IntptrTy, LocalStackSize));
3734 Value *NoFakeStack =
3739 Value *AllocaValue =
3740 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3744 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3745 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3753 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3754 LocalStackBaseAlloca = LocalStackBase;
3759 for (
const auto &
Desc : SVD) {
3763 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3776 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3784 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3791 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3794 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3796 if (!StaticAllocaPoisonCallVec.empty()) {
3800 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3803 size_t Begin =
Desc.Offset /
L.Granularity;
3804 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3807 copyToShadow(ShadowAfterScope,
3808 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3814 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3817 if (
I->isLifetimeStartOrEnd())
3818 I->eraseFromParent();
3831 if (DoStackMalloc) {
3832 assert(StackMallocIdx >= 0);
3849 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3851 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3853 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3855 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3857 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3858 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3859 IRBPoison.CreateStore(
3861 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3864 RTCI.createRuntimeCall(
3865 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3866 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3870 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3872 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3877 for (
auto *AI : AllocaVec)
3885 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3886 RTCI.createRuntimeCall(
3887 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3888 {AddrArg, SizeArg});
3899void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3907 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3941 ConstantInt::get(IntptrTy,
Alignment.value()));
3944 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3955 if (
I->isLifetimeStartOrEnd())
3956 I->eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > ClUseStackSafety("stack-tagging-use-stack-safety", cl::Hidden, cl::init(true), cl::desc("Use Stack Safety analysis results"))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void findStoresToUninstrumentedArgAllocas(AddressSanitizer &ASan, Instruction &InsBefore, SmallVectorImpl< Instruction * > &InitInsts)
Collect instructions in the entry block after InsBefore which initialize permanent storage for a func...
static cl::opt< bool > ClUseStackSafety("asan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"))
static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I, Instruction *InsertBefore, Value *Addr, MaybeAlign Alignment, unsigned Granularity, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp, RuntimeCallInserter &RTCI)
static const uint64_t kDefaultShadowScale
const char kAMDGPUUnreachableName[]
constexpr size_t kAccessSizeIndexMask
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClUsePrivateAlias("asan-use-private-alias", cl::desc("Use private aliases for global variables"), cl::Hidden, cl::init(true))
static const uint64_t kPS_ShadowOffset64
static const uint64_t kFreeBSD_ShadowOffset32
constexpr size_t kIsWriteShift
static const uint64_t kSmallX86_64ShadowOffsetAlignMask
static bool isInterestingPointerSubtraction(Instruction *I)
const char kAMDGPUAddressSharedName[]
const char kAsanStackFreeNameTemplate[]
constexpr size_t kCompileKernelMask
static cl::opt< bool > ClForceDynamicShadow("asan-force-dynamic-shadow", cl::desc("Load shadow address into a local variable for each function"), cl::Hidden, cl::init(false))
const char kAsanOptionDetectUseAfterReturn[]
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static const uint64_t kRISCV64_ShadowOffset64
static cl::opt< bool > ClInsertVersionCheck("asan-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
const char kAsanSetShadowPrefix[]
static cl::opt< AsanDtorKind > ClOverrideDestructorKind("asan-destructor-kind", cl::desc("Sets the ASan destructor kind. The default is to use the value " "provided to the pass constructor"), cl::values(clEnumValN(AsanDtorKind::None, "none", "No destructors"), clEnumValN(AsanDtorKind::Global, "global", "Use global destructors")), cl::init(AsanDtorKind::Invalid), cl::Hidden)
static Twine genName(StringRef suffix)
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static uint64_t GetCtorAndDtorPriority(Triple &TargetTriple)
const char kAsanStackMallocNameTemplate[]
static cl::opt< bool > ClInstrumentByval("asan-instrument-byval", cl::desc("instrument byval call arguments"), cl::Hidden, cl::init(true))
const char kAsanInitName[]
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClRedzoneByvalArgs("asan-redzone-byval-args", cl::desc("Create redzones for byval " "arguments (extra copy " "required)"), cl::Hidden, cl::init(true))
static bool isPointerPairOperand(Value *V, Type *IntptrTy)
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
static cl::opt< bool > ClOptimizeCallbacks("asan-optimize-callbacks", cl::desc("Optimize callbacks"), cl::Hidden, cl::init(false))
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(true))
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static cl::opt< int > ClShadowAddrSpace("asan-shadow-addr-space", cl::desc("Address space for pointers to the shadow map"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClInvalidPointerCmp("asan-detect-invalid-pointer-cmp", cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInvalidPointerSub("asan-detect-invalid-pointer-sub", cl::desc("Instrument - operations with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static cl::list< unsigned > ClAddrSpaces("asan-instrument-address-spaces", cl::desc("Only instrument variables in the specified address spaces."), cl::Hidden, cl::CommaSeparated, cl::callback([](const unsigned &AddrSpace) { SrcAddrSpaces.insert(AddrSpace);}))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
constexpr size_t kAccessSizeIndexShift
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
const char kAsanPoisonStackMemoryName[]
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isSupportedAddrspace(const Triple &TargetTriple, Value *Addr)
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static cl::opt< AsanDetectStackUseAfterReturnMode > ClUseAfterReturn("asan-use-after-return", cl::desc("Sets the mode of detection for stack-use-after-return."), cl::values(clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", "Never detect stack use after return."), clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, "runtime", "Detect stack use after return if " "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", "Always detect stack use after return.")), cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime))
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static const uintptr_t kCurrentStackFrameMagic
static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kPPC64_ShadowOffset64
static cl::opt< AsanCtorKind > ClConstructorKind("asan-constructor-kind", cl::desc("Sets the ASan constructor kind"), cl::values(clEnumValN(AsanCtorKind::None, "none", "No constructors"), clEnumValN(AsanCtorKind::Global, "global", "Use global constructors")), cl::init(AsanCtorKind::Global), cl::Hidden)
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
static const uint64_t kNetBSD_ShadowOffset64
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
static const uint64_t kWindowsShadowOffset32
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
static SmallSet< unsigned, 8 > SrcAddrSpaces
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const char kAsanReportErrorTemplate[]
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
static StringRef getAllocaName(AllocaInst *AI)
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
static const uintptr_t kRetiredStackFrameMagic
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
static cl::opt< int > ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
static cl::opt< bool > ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, cl::init(false))
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool isPointerOperand(Value *I, User *U)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
uint64_t getZExtValue() const
Get zero extended value.
int64_t getSExtValue() const
Get sign extended value.
LLVM_ABI AddressSanitizerPass(const AddressSanitizerOptions &Options, bool UseGlobalGC=true, bool UseOdrIndicator=true, AsanDtorKind DestructorKind=AsanDtorKind::Global, AsanCtorKind ConstructorKind=AsanCtorKind::Global)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
void setAlignment(Align Align)
This class represents an incoming formal argument to a Function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
Class to represent array types.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
bool isInlineAsm() const
Check if this call is an inline asm statement.
static LLVM_ABI CallBase * addOperandBundle(CallBase *CB, uint32_t ID, OperandBundleDef OB, InsertPosition InsertPt=nullptr)
Create a clone of CB with operand bundle OB added.
bool doesNotReturn() const
Determine if the call cannot return.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
@ Largest
The linker will choose the largest COMDAT.
@ SameSize
The data referenced by the COMDAT must be the same size.
@ Any
The linker may choose any COMDAT.
@ NoDeduplicate
No deduplication is performed.
@ ExactMatch
The data referenced by the COMDAT must be the same.
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
ConstantArray - Constant Array Declarations.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI bool isValueValidForType(Type *Ty, uint64_t V)
This static method returns true if the type Ty is big enough to represent the value V.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
DILocation * get() const
Get the underlying DILocation.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
const BasicBlock & front() const
DISubprogram * getSubprogram() const
Get the attached subprogram.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
bool hasPersonalityFn() const
Check whether this function has a personality function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
const Constant * getAliasee() const
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
LLVM_ABI void copyMetadata(const GlobalObject *Src, unsigned Offset)
Copy metadata from Src, adjusting offsets by Offset.
LLVM_ABI void setComdat(Comdat *C)
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
VisibilityTypes getVisibility() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
ThreadLocalMode getThreadLocalMode() const
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
DLLStorageClassTypes getDLLStorageClass() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
Common base class shared among various IRBuilders.
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNull=false)
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
BasicBlock * GetInsertBlock() const
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Base class for instruction visitors.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
iterator_range< user_iterator > users()
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
An instruction for reading from memory.
static Error ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
Parse the section specifier indicated by "Spec".
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
ArrayRef< MDOperand > operands() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This is the common base class for memset/memcpy/memmove.
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
static MemoryEffectsBase otherMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
A Module instance is used to store all the information related to an LLVM module.
Evaluate the size and offset of an object pointed to by a Value* statically.
LLVM_ABI SizeOffsetAPInt compute(Value *V)
Pass interface - Implemented by all 'passes'.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Return a value (possibly void), from a function.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
LLVM_ABI bool stackAccessIsSafe(const Instruction &I) const
LLVM_ABI bool isSafe(const AllocaInst &AI) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
Triple - Helper class for working with autoconf configuration names.
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
bool isDriverKit() const
Is this an Apple DriverKit triple.
bool isBPF() const
Tests whether the target is eBPF.
bool isAndroid() const
Tests whether the target is Android.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isOSWindows() const
Tests whether the OS is Windows.
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isOSLinux() const
Tests whether the OS is Linux.
bool isMacOSX() const
Is this a Mac OS X triple.
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
bool isWatchOS() const
Is this an Apple watchOS triple.
bool isiOS() const
Is this an iOS triple.
bool isPS() const
Tests whether the target is the PS4 or PS5 platform.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
bool isOSHaiku() const
Tests whether the OS is Haiku.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This class implements an extremely fast bulk output stream that can only output to a stream.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void getInterestingMemoryOperands(Module &M, Instruction *I, SmallVectorImpl< InterestingMemoryOperand > &Interesting)
Get all the memory operands from the instruction that needs to be instrumented.
void instrumentAddress(Module &M, IRBuilder<> &IRB, Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, Align Alignment, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, bool Recover, int AsanScale, int AsanOffset)
Instrument the memory operand Addr.
uint64_t getRedzoneSizeForGlobal(int AsanScale, uint64_t SizeInBytes)
Given SizeInBytes of the Value to be instrunmented, Returns the redzone size corresponding to it.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
@ S_CSTRING_LITERALS
S_CSTRING_LITERALS - Section with literal C strings.
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
cb< typename detail::callback_traits< F >::result_type, typename detail::callback_traits< F >::arg_type > callback(F CB)
LLVM_ABI uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
LLVM_ABI GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, Twine NamePrefix="")
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
AsanDetectStackUseAfterReturnMode
Mode of ASan detect stack use after return.
@ Always
Always detect stack use after return.
@ Never
Never detect stack use after return.
@ Runtime
Detect stack use after return if not disabled runtime with (ASAN_OPTIONS=detect_stack_use_after_retur...
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
LLVM_ABI SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI SmallVector< uint8_t, 64 > GetShadowBytes(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
AsanDtorKind
Types of ASan module destructors supported.
@ Invalid
Not a valid destructor Kind.
@ Global
Append to llvm.global_dtors.
@ None
Do not emit any destructors for ASan.
LLVM_ABI ASanStackFrameLayout ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, uint64_t Granularity, uint64_t MinHeaderSize)
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
OperandBundleDefT< Value * > OperandBundleDef
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
static const int kAsanStackUseAfterReturnMagic
LLVM_ABI void setGlobalVariableLargeSection(const Triple &TargetTriple, GlobalVariable &GV)
LLVM_ABI void removeASanIncompatibleFnAttributes(Function &F, bool ReadsArgMem)
Remove memory attributes that are incompatible with the instrumentation added by AddressSanitizer and...
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isModAndRefSet(const ModRefInfo MRI)
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
TinyPtrVector< BasicBlock * > ColorVector
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AsanCtorKind
Types of ASan module constructors supported.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
LLVM_ABI void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
std::string itostr(int64_t X)
LLVM_ABI void SplitBlockAndInsertForEachLane(ElementCount EC, Type *IndexTy, BasicBlock::iterator InsertBefore, std::function< void(IRBuilderBase &, Value *)> Func)
Utility function for performing a given action on each lane of a vector with EC elements.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset)
Replaces dbg.declare record when the address it describes is replaced with a new value.
LLVM_ABI ASanAccessInfo(int32_t Packed)
const uint8_t AccessSizeIndex
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Information about a load/store intrinsic defined by the target.
SmallVector< InterestingMemoryOperand, 1 > InterestingOperands
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.