97#define DEBUG_TYPE "asan"
103 std::numeric_limits<uint64_t>::max();
144 "__asan_unregister_image_globals";
157 "__asan_stack_malloc_always_";
171 "__asan_option_detect_stack_use_after_return";
174 "__asan_shadow_memory_dynamic_address";
200 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
205 cl::desc(
"Enable recovery mode (continue-after-error)."),
209 "asan-guard-against-version-mismatch",
215 cl::desc(
"instrument read instructions"),
219 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
227 "asan-instrument-atomics",
237 "asan-always-slow-path",
242 "asan-force-dynamic-shadow",
243 cl::desc(
"Load shadow address into a local variable for each function"),
248 cl::desc(
"Access dynamic shadow through an ifunc global on "
249 "platforms that support this"),
254 cl::desc(
"Address space for pointers to the shadow map"),
258 "asan-with-ifunc-suppress-remat",
259 cl::desc(
"Suppress rematerialization of dynamic shadow address by passing "
260 "it through inline asm in prologue."),
268 "asan-max-ins-per-bb",
cl::init(10000),
269 cl::desc(
"maximal number of instructions to instrument in any given BB"),
276 "asan-max-inline-poisoning-size",
278 "Inline shadow poisoning for blocks up to the given size in bytes."),
282 "asan-use-after-return",
283 cl::desc(
"Sets the mode of detection for stack-use-after-return."),
286 "Never detect stack use after return."),
289 "Detect stack use after return if "
290 "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."),
292 "Always detect stack use after return.")),
296 cl::desc(
"Create redzones for byval "
297 "arguments (extra copy "
302 cl::desc(
"Check stack-use-after-scope"),
311 cl::desc(
"Handle C++ initializer order"),
315 "asan-detect-invalid-pointer-pair",
320 "asan-detect-invalid-pointer-cmp",
325 "asan-detect-invalid-pointer-sub",
330 "asan-realign-stack",
331 cl::desc(
"Realign stack to the value of this flag (power of two)"),
335 "asan-instrumentation-with-call-threshold",
336 cl::desc(
"If the function being instrumented contains more than "
337 "this number of memory accesses, use callbacks instead of "
338 "inline checks (-1 means never use callbacks)."),
342 "asan-memory-access-callback-prefix",
347 "asan-kernel-mem-intrinsic-prefix",
353 cl::desc(
"instrument dynamic allocas"),
357 "asan-skip-promotable-allocas",
362 "asan-constructor-kind",
363 cl::desc(
"Sets the ASan constructor kind"),
366 "Use global constructors")),
373 cl::desc(
"scale of asan shadow mapping"),
378 cl::desc(
"offset of asan shadow mapping [EXPERIMENTAL]"),
392 "asan-opt-same-temp",
cl::desc(
"Instrument the same temp just once"),
396 cl::desc(
"Don't instrument scalar globals"),
400 "asan-opt-stack",
cl::desc(
"Don't instrument scalar stack variables"),
404 "asan-stack-dynamic-alloca",
409 "asan-force-experiment",
415 cl::desc(
"Use private aliases for global variables"),
420 cl::desc(
"Use odr indicators to improve ODR reporting"),
425 cl::desc(
"Use linker features to support dead "
426 "code stripping of globals"),
433 cl::desc(
"Place ASan constructors in comdat sections"),
437 "asan-destructor-kind",
438 cl::desc(
"Sets the ASan destructor kind. The default is to use the value "
439 "provided to the pass constructor"),
442 "Use global destructors")),
446 "asan-instrument-address-spaces",
447 cl::desc(
"Only instrument variables in the specified address spaces."),
464STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
465STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
467 "Number of optimized accesses to global vars");
469 "Number of optimized accesses to stack vars");
478struct ShadowMapping {
489 bool IsAndroid = TargetTriple.
isAndroid();
492 bool IsMacOS = TargetTriple.
isMacOSX();
495 bool IsPS = TargetTriple.
isPS();
501 bool IsMIPSN32ABI = TargetTriple.
isABIN32();
502 bool IsMIPS32 = TargetTriple.
isMIPS32();
503 bool IsMIPS64 = TargetTriple.
isMIPS64();
504 bool IsArmOrThumb = TargetTriple.
isARM() || TargetTriple.
isThumb();
511 bool IsAMDGPU = TargetTriple.
isAMDGPU();
513 bool IsWasm = TargetTriple.
isWasm();
514 bool IsBPF = TargetTriple.
isBPF();
516 ShadowMapping Mapping;
523 if (LongSize == 32) {
526 else if (IsMIPSN32ABI)
552 else if (IsFreeBSD && IsAArch64)
554 else if (IsFreeBSD && !IsMIPS64) {
559 }
else if (IsNetBSD) {
566 else if (IsLinux && IsX86_64) {
572 }
else if (IsWindows && (IsX86_64 || IsAArch64)) {
578 else if (IsMacOS && IsAArch64)
582 else if (IsLoongArch64)
589 else if (IsHaiku && IsX86_64)
613 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
614 !IsRISCV64 && !IsLoongArch64 &&
615 !(Mapping.Offset & (Mapping.Offset - 1)) &&
617 Mapping.InGlobal =
ClWithIfunc && IsAndroid && IsArmOrThumb;
623 bool IsKasan, uint64_t *ShadowBase,
624 int *MappingScale,
bool *OrShadowOffset) {
626 *ShadowBase = Mapping.Offset;
627 *MappingScale = Mapping.Scale;
628 *OrShadowOffset = Mapping.OrShadowOffset;
649 if (!
F.getMemoryEffects()
651 .doesNotAccessMemory() &&
653 F.setMemoryEffects(
F.getMemoryEffects() |
661 F.setMemoryEffects(
F.getMemoryEffects() |
666 if (
A.hasAttribute(Attribute::WriteOnly)) {
667 A.removeAttr(Attribute::WriteOnly);
675 F.addFnAttr(Attribute::NoBuiltin);
696 return std::max(32U, 1U << MappingScale);
712class AsanFunctionInserter {
714 AsanFunctionInserter(
Module &M) :
M(
M) {}
716 template <
typename... ArgTypes>
717 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
718 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
731class RuntimeCallInserter {
733 bool TrackInsertedCalls =
false;
737 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
739 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
740 if (isScopedEHPersonality(Personality))
741 TrackInsertedCalls = true;
745 ~RuntimeCallInserter() {
746 if (InsertedCalls.
empty())
748 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
750 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
751 for (CallInst *CI : InsertedCalls) {
753 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
755 "Instruction doesn't belong to the expected Function!");
763 if (Colors.
size() != 1) {
765 "Instruction's BasicBlock is not monochromatic");
772 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
776 OB, CI->getIterator());
777 NewCall->copyMetadata(*CI);
778 CI->replaceAllUsesWith(NewCall);
779 CI->eraseFromParent();
784 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
786 const Twine &
Name =
"") {
789 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
790 if (TrackInsertedCalls)
791 InsertedCalls.push_back(Inst);
797struct AddressSanitizer {
798 AddressSanitizer(
Module &M,
const StackSafetyGlobalInfo *SSGI,
799 int InstrumentationWithCallsThreshold,
800 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
801 bool Recover =
false,
bool UseAfterScope =
false,
803 AsanDetectStackUseAfterReturnMode::Runtime)
812 InstrumentationWithCallsThreshold(
815 : InstrumentationWithCallsThreshold),
818 : MaxInlinePoisoningSize) {
819 C = &(
M.getContext());
820 DL = &
M.getDataLayout();
821 LongSize =
M.getDataLayout().getPointerSizeInBits();
822 IntptrTy = Type::getIntNTy(*
C, LongSize);
823 PtrTy = PointerType::getUnqual(*
C);
824 Int32Ty = Type::getInt32Ty(*
C);
825 TargetTriple =
M.getTargetTriple();
829 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
837 bool isInterestingAlloca(
const AllocaInst &AI);
839 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
841 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
842 const TargetTransformInfo *
TTI);
844 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
845 InterestingMemoryOperand &O,
bool UseCalls,
846 const DataLayout &
DL, RuntimeCallInserter &RTCI);
847 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
848 RuntimeCallInserter &RTCI);
850 Value *Addr, MaybeAlign Alignment,
851 uint32_t TypeStoreSize,
bool IsWrite,
852 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
853 RuntimeCallInserter &RTCI);
854 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
855 Instruction *InsertBefore,
Value *Addr,
856 uint32_t TypeStoreSize,
bool IsWrite,
857 Value *SizeArgument);
860 void instrumentUnusualSizeOrAlignment(Instruction *
I,
861 Instruction *InsertBefore,
Value *Addr,
862 TypeSize TypeStoreSize,
bool IsWrite,
863 Value *SizeArgument,
bool UseCalls,
865 RuntimeCallInserter &RTCI);
866 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
869 MaybeAlign Alignment,
unsigned Granularity,
870 Type *OpType,
bool IsWrite,
871 Value *SizeArgument,
bool UseCalls,
872 uint32_t Exp, RuntimeCallInserter &RTCI);
874 Value *ShadowValue, uint32_t TypeStoreSize);
876 bool IsWrite,
size_t AccessSizeIndex,
877 Value *SizeArgument, uint32_t Exp,
878 RuntimeCallInserter &RTCI);
879 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
881 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
882 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
883 const TargetTransformInfo *
TTI);
884 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
885 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
886 void markEscapedLocalAllocas(
Function &
F);
887 void markCatchParametersAsUninteresting(
Function &
F);
890 friend struct FunctionStackPoisoner;
892 void initializeCallbacks(
const TargetLibraryInfo *TLI);
894 bool LooksLikeCodeInBug11395(Instruction *
I);
895 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
896 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
897 TypeSize TypeStoreSize)
const;
900 struct FunctionStateRAII {
901 AddressSanitizer *
Pass;
903 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
905 "last pass forgot to clear cache");
909 ~FunctionStateRAII() {
910 Pass->LocalDynamicShadow =
nullptr;
911 Pass->ProcessedAllocas.clear();
916 AsanFunctionInserter Inserter;
918 const DataLayout *
DL;
928 ShadowMapping Mapping;
929 FunctionCallee AsanHandleNoReturnFunc;
930 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
938 FunctionCallee AsanErrorCallbackSized[2][2];
939 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
941 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
942 Value *LocalDynamicShadow =
nullptr;
943 const StackSafetyGlobalInfo *SSGI;
944 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
946 FunctionCallee AMDGPUAddressShared;
947 FunctionCallee AMDGPUAddressPrivate;
948 int InstrumentationWithCallsThreshold;
949 uint32_t MaxInlinePoisoningSize;
952class ModuleAddressSanitizer {
954 ModuleAddressSanitizer(
Module &M,
bool InsertVersionCheck,
955 bool CompileKernel =
false,
bool Recover =
false,
956 bool UseGlobalsGC =
true,
bool UseOdrIndicator =
true,
964 : InsertVersionCheck),
966 UseGlobalsGC(UseGlobalsGC &&
ClUseGlobalsGC && !this->CompileKernel),
981 UseCtorComdat(UseGlobalsGC &&
ClWithComdat && !this->CompileKernel),
982 DestructorKind(DestructorKind),
986 C = &(
M.getContext());
987 int LongSize =
M.getDataLayout().getPointerSizeInBits();
988 IntptrTy = Type::getIntNTy(*
C, LongSize);
989 PtrTy = PointerType::getUnqual(*
C);
990 TargetTriple =
M.getTargetTriple();
995 assert(this->DestructorKind != AsanDtorKind::Invalid);
998 bool instrumentModule();
1001 void initializeCallbacks();
1003 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
1010 const std::string &UniqueModuleId);
1015 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
1019 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
1020 StringRef OriginalName);
1021 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
1022 StringRef InternalSuffix);
1025 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
1026 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
1027 bool ShouldUseMachOGlobalsSection()
const;
1028 StringRef getGlobalMetadataSection()
const;
1029 void poisonOneInitializer(
Function &GlobalInit);
1030 void createInitializerPoisonCalls();
1031 uint64_t getMinRedzoneSizeForGlobal()
const {
1035 int GetAsanVersion()
const;
1036 GlobalVariable *getOrCreateModuleName();
1039 AsanFunctionInserter Inserter;
1041 bool InsertVersionCheck;
1044 bool UsePrivateAlias;
1045 bool UseOdrIndicator;
1052 Triple TargetTriple;
1053 ShadowMapping Mapping;
1054 FunctionCallee AsanPoisonGlobals;
1055 FunctionCallee AsanUnpoisonGlobals;
1056 FunctionCallee AsanRegisterGlobals;
1057 FunctionCallee AsanUnregisterGlobals;
1058 FunctionCallee AsanRegisterImageGlobals;
1059 FunctionCallee AsanUnregisterImageGlobals;
1060 FunctionCallee AsanRegisterElfGlobals;
1061 FunctionCallee AsanUnregisterElfGlobals;
1063 Function *AsanCtorFunction =
nullptr;
1064 Function *AsanDtorFunction =
nullptr;
1065 GlobalVariable *ModuleName =
nullptr;
1077struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
1079 AddressSanitizer &ASan;
1080 RuntimeCallInserter &RTCI;
1085 ShadowMapping Mapping;
1089 SmallVector<Instruction *, 8> RetVec;
1093 FunctionCallee AsanSetShadowFunc[0x100] = {};
1094 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
1095 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
1098 struct AllocaPoisonCall {
1099 IntrinsicInst *InsBefore;
1109 AllocaInst *DynamicAllocaLayout =
nullptr;
1110 IntrinsicInst *LocalEscapeCall =
nullptr;
1112 bool HasInlineAsm =
false;
1113 bool HasReturnsTwiceCall =
false;
1116 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
1117 RuntimeCallInserter &RTCI)
1118 :
F(
F), ASan(ASan), RTCI(RTCI),
1120 IntptrTy(ASan.IntptrTy),
1122 Mapping(ASan.Mapping),
1130 copyArgsPassedByValToAllocas();
1135 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
1137 initializeCallbacks(*
F.getParent());
1139 processDynamicAllocas();
1140 processStaticAllocas();
1151 void copyArgsPassedByValToAllocas();
1156 void processStaticAllocas();
1157 void processDynamicAllocas();
1159 void createDynamicAllocasInitStorage();
1164 void visitReturnInst(ReturnInst &RI) {
1165 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
1172 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
1175 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
1177 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
1178 Value *SavedStack) {
1187 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
1193 RTCI.createRuntimeCall(
1194 IRB, AsanAllocasUnpoisonFunc,
1195 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
1199 void unpoisonDynamicAllocas() {
1200 for (Instruction *Ret : RetVec)
1201 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
1203 for (Instruction *StackRestoreInst : StackRestoreVec)
1204 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
1205 StackRestoreInst->getOperand(0));
1218 void handleDynamicAllocaCall(AllocaInst *AI);
1221 void visitAllocaInst(AllocaInst &AI) {
1223 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
1227 if (AllocaVec.
empty())
1243 void visitIntrinsicInst(IntrinsicInst &
II) {
1245 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
1246 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
1247 if (!ASan.UseAfterScope)
1249 if (!
II.isLifetimeStartOrEnd())
1254 if (!AI || !ASan.isInterestingAlloca(*AI))
1264 bool DoPoison = (
ID == Intrinsic::lifetime_end);
1265 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
1267 StaticAllocaPoisonCallVec.
push_back(APC);
1269 DynamicAllocaPoisonCallVec.
push_back(APC);
1272 void visitCallBase(CallBase &CB) {
1274 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1275 HasReturnsTwiceCall |= CI->canReturnTwice();
1280 void initializeCallbacks(
Module &M);
1285 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1287 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1290 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1291 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1296 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1299 Instruction *ThenTerm,
Value *ValueIfFalse);
1306 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1307 OS, MapClassName2PassName);
1309 if (Options.CompileKernel)
1311 if (Options.UseAfterScope)
1312 OS <<
"use-after-scope";
1320 : Options(Options), UseGlobalGC(UseGlobalGC),
1321 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1322 ConstructorKind(ConstructorKind) {}
1331 ModuleAddressSanitizer ModuleSanitizer(
1332 M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
1333 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
1345 if (
F.getName().starts_with(
"__asan_"))
1347 if (
F.isPresplitCoroutine())
1349 AddressSanitizer FunctionSanitizer(
1350 M, SSGI, Options.InstrumentationWithCallsThreshold,
1351 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1352 Options.UseAfterScope, Options.UseAfterReturn);
1355 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1357 Modified |= ModuleSanitizer.instrumentModule();
1378 if (
G->getName().starts_with(
"llvm.") ||
1380 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1382 G->getName().starts_with(
"__llvm_rtti_proxy"))
1398 if (AddrSpace == 3 || AddrSpace == 5)
1413 return AddrSpace == 0;
1417 if (TargetTriple.isOSDarwin() &&
1421 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1424 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1425 if (Mapping.Offset == 0)
return Shadow;
1428 if (LocalDynamicShadow)
1429 ShadowBase = LocalDynamicShadow;
1431 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1432 if (Mapping.OrShadowOffset)
1433 return IRB.
CreateOr(Shadow, ShadowBase);
1435 return IRB.
CreateAdd(Shadow, ShadowBase);
1440 RuntimeCallInserter &RTCI) {
1443 RTCI.createRuntimeCall(
1449 RTCI.createRuntimeCall(
1455 MI->eraseFromParent();
1459bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1460 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1463 return It->getSecond();
1465 bool IsInteresting =
1476 !(SSGI && SSGI->
isSafe(AI)));
1478 It->second = IsInteresting;
1479 return IsInteresting;
1509void AddressSanitizer::getInterestingMemoryOperands(
1513 if (LocalDynamicShadow ==
I)
1519 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1520 LI->getType(), LI->getAlign());
1525 SI->getValueOperand()->getType(),
SI->getAlign());
1529 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1530 RMW->getValOperand()->getType(), std::nullopt);
1534 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1535 XCHG->getCompareOperand()->getType(),
1538 switch (CI->getIntrinsicID()) {
1539 case Intrinsic::masked_load:
1540 case Intrinsic::masked_store:
1541 case Intrinsic::masked_gather:
1542 case Intrinsic::masked_scatter: {
1543 bool IsWrite = CI->getType()->isVoidTy();
1545 unsigned OpOffset = IsWrite ? 1 : 0;
1549 auto BasePtr = CI->getOperand(OpOffset);
1550 if (ignoreAccess(
I, BasePtr))
1552 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1554 Value *
Mask = CI->getOperand(1 + OpOffset);
1555 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1558 case Intrinsic::masked_expandload:
1559 case Intrinsic::masked_compressstore: {
1560 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1561 unsigned OpOffset = IsWrite ? 1 : 0;
1564 auto BasePtr = CI->getOperand(OpOffset);
1565 if (ignoreAccess(
I, BasePtr))
1568 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1571 Value *
Mask = CI->getOperand(1 + OpOffset);
1574 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1575 Value *EVL =
IB.CreateAddReduce(ExtMask);
1576 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1577 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1581 case Intrinsic::vp_load:
1582 case Intrinsic::vp_store:
1583 case Intrinsic::experimental_vp_strided_load:
1584 case Intrinsic::experimental_vp_strided_store: {
1586 unsigned IID = CI->getIntrinsicID();
1587 bool IsWrite = CI->getType()->isVoidTy();
1590 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1591 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1593 Value *Stride =
nullptr;
1594 if (IID == Intrinsic::experimental_vp_strided_store ||
1595 IID == Intrinsic::experimental_vp_strided_load) {
1596 Stride = VPI->getOperand(PtrOpNo + 1);
1600 unsigned PointerAlign =
Alignment.valueOrOne().value();
1605 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1606 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1610 case Intrinsic::vp_gather:
1611 case Intrinsic::vp_scatter: {
1613 unsigned IID = CI->getIntrinsicID();
1614 bool IsWrite = IID == Intrinsic::vp_scatter;
1617 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1618 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1620 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1621 VPI->getMaskParam(),
1622 VPI->getVectorLengthParam());
1628 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1632 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1634 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1636 Type *Ty = CI->getParamByValType(ArgNo);
1652 if (!Cmp->isRelational())
1666 if (BO->getOpcode() != Instruction::Sub)
1679 if (!
G->hasInitializer())
1682 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1689 Type *Ty = V->getType();
1690 if (Ty->isPtrOrPtrVectorTy())
1696bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1698 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1713 "invalid vector pointer pair instrumentation operands");
1714 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1715 Index != NumElements; ++Index) {
1716 Value *ScalarParam[2] = {
1723 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1730 RTCI.createRuntimeCall(IRB,
F, Param);
1737 TypeSize TypeStoreSize,
bool IsWrite,
1738 Value *SizeArgument,
bool UseCalls,
1739 uint32_t Exp, RuntimeCallInserter &RTCI) {
1744 switch (FixedSize) {
1750 if (!Alignment || *Alignment >= Granularity ||
1751 *Alignment >= FixedSize / 8)
1752 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1753 FixedSize, IsWrite,
nullptr, UseCalls,
1757 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1758 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1761void AddressSanitizer::instrumentMaskedLoadOrStore(
1764 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1765 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1766 RuntimeCallInserter &RTCI) {
1768 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1769 auto Zero = ConstantInt::get(IntptrTy, 0);
1777 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1779 IB.SetInsertPoint(LoopInsertBefore);
1781 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1784 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1785 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1787 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1792 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1796 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1797 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1798 if (MaskElemC->isZero())
1804 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1805 MaskElem, &*IRB.GetInsertPoint(), false);
1806 IRB.SetInsertPoint(ThenTerm);
1809 Value *InstrumentedAddress;
1812 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1813 "Expected vector of pointer.");
1814 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1815 }
else if (Stride) {
1822 Alignment, Granularity, ElemTypeSize, IsWrite,
1823 SizeArgument, UseCalls, Exp, RTCI);
1830 RuntimeCallInserter &RTCI) {
1831 Value *Addr =
O.getPtr();
1851 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1852 NumOptimizedAccessesToGlobalVar++;
1860 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1861 NumOptimizedAccessesToStackVar++;
1867 NumInstrumentedWrites++;
1869 NumInstrumentedReads++;
1871 if (
O.MaybeByteOffset) {
1876 if (TargetTriple.isRISCV()) {
1881 static_cast<unsigned>(LongSize)) {
1890 unsigned Granularity = 1 << Mapping.Scale;
1892 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1893 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1894 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1895 UseCalls, Exp, RTCI);
1898 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1899 UseCalls, Exp, RTCI);
1904 Value *Addr,
bool IsWrite,
1905 size_t AccessSizeIndex,
1906 Value *SizeArgument,
1908 RuntimeCallInserter &RTCI) {
1914 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1915 {Addr, SizeArgument});
1917 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1918 {Addr, SizeArgument, ExpVal});
1921 Call = RTCI.createRuntimeCall(
1922 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1924 Call = RTCI.createRuntimeCall(
1925 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1934 uint32_t TypeStoreSize) {
1935 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1937 Value *LastAccessedByte =
1938 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1940 if (TypeStoreSize / 8 > 1)
1942 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1945 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1950Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1952 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1959 return InsertBefore;
1964 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1966 Value *AddrSpaceZeroLanding =
1969 return InsertBefore;
1984 Trm->getParent()->setName(
"asan.report");
1995void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1998 uint32_t TypeStoreSize,
bool IsWrite,
1999 Value *SizeArgument,
bool UseCalls,
2001 RuntimeCallInserter &RTCI) {
2002 if (TargetTriple.isAMDGPU()) {
2003 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
2004 TypeStoreSize, IsWrite, SizeArgument);
2013 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
2016 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
2023 RTCI.createRuntimeCall(
2024 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
2026 RTCI.createRuntimeCall(
2027 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
2028 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
2035 Value *ShadowPtr = memToShadow(AddrLong, IRB);
2037 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
2042 size_t Granularity = 1ULL << Mapping.Scale;
2045 bool GenSlowPath = (
ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
2047 if (TargetTriple.isAMDGCN()) {
2049 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2052 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2053 }
else if (GenSlowPath) {
2060 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2075 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2084void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2086 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
2087 uint32_t Exp, RuntimeCallInserter &RTCI) {
2095 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2098 RTCI.createRuntimeCall(
2099 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2113void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
2118 Value *ModuleNameAddr =
2126 for (
auto &BB : GlobalInit)
2138void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2158 poisonOneInitializer(*
F);
2164ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
2169 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
2181bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
2182 Type *Ty =
G->getValueType();
2185 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
2187 if (!Ty->
isSized())
return false;
2188 if (!
G->hasInitializer())
return false;
2195 if (
G->isThreadLocal())
return false;
2197 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
2203 if (!TargetTriple.isOSBinFormatCOFF()) {
2204 if (!
G->hasExactDefinition() ||
G->hasComdat())
2208 if (
G->isInterposable())
2212 if (
G->hasAvailableExternallyLinkage())
2219 switch (
C->getSelectionKind()) {
2230 if (
G->hasSection()) {
2240 if (Section ==
"llvm.metadata")
return false;
2247 if (
Section.starts_with(
".preinit_array") ||
2248 Section.starts_with(
".init_array") ||
2249 Section.starts_with(
".fini_array")) {
2255 if (TargetTriple.isOSBinFormatELF()) {
2269 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2270 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2275 if (TargetTriple.isOSBinFormatMachO()) {
2277 unsigned TAA = 0, StubSize = 0;
2280 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2285 if (ParsedSegment ==
"__OBJC" ||
2286 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2298 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2311 if (CompileKernel) {
2314 if (
G->getName().starts_with(
"__"))
2324bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2325 if (!TargetTriple.isOSBinFormatMachO())
2328 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2330 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2332 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2334 if (TargetTriple.isDriverKit())
2336 if (TargetTriple.isXROS())
2342StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2343 switch (TargetTriple.getObjectFormat()) {
2353 "ModuleAddressSanitizer not implemented for object file format");
2360void ModuleAddressSanitizer::initializeCallbacks() {
2366 AsanUnpoisonGlobals =
2370 AsanRegisterGlobals = Inserter.insertFunction(
2372 AsanUnregisterGlobals = Inserter.insertFunction(
2377 AsanRegisterImageGlobals = Inserter.insertFunction(
2379 AsanUnregisterImageGlobals = Inserter.insertFunction(
2382 AsanRegisterElfGlobals =
2384 IntptrTy, IntptrTy, IntptrTy);
2385 AsanUnregisterElfGlobals =
2387 IntptrTy, IntptrTy, IntptrTy);
2392void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2397 if (!
G->hasName()) {
2401 G->setName(
genName(
"anon_global"));
2404 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2405 std::string
Name = std::string(
G->getName());
2406 Name += InternalSuffix;
2407 C =
M.getOrInsertComdat(Name);
2409 C =
M.getOrInsertComdat(
G->getName());
2415 if (TargetTriple.isOSBinFormatCOFF()) {
2417 if (
G->hasPrivateLinkage())
2430ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2432 auto Linkage = TargetTriple.isOSBinFormatMachO()
2438 Metadata->setSection(getGlobalMetadataSection());
2445Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2449 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2457void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2461 auto &
DL =
M.getDataLayout();
2464 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2465 Constant *Initializer = MetadataInitializers[i];
2469 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2475 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2477 "global metadata will not be padded appropriately");
2480 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2485 if (!MetadataGlobals.empty())
2489void ModuleAddressSanitizer::instrumentGlobalsELF(
2492 const std::string &UniqueModuleId) {
2499 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2502 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2505 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2507 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2510 if (UseComdatForGlobalsGC)
2511 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2516 if (!MetadataGlobals.empty())
2533 "__start_" + getGlobalMetadataSection());
2537 "__stop_" + getGlobalMetadataSection());
2551 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2558void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2569 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2570 Constant *Initializer = MetadataInitializers[i];
2576 auto LivenessBinder =
2581 Twine(
"__asan_binder_") +
G->getName());
2582 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2583 LivenessGlobals[i] = Liveness;
2590 if (!LivenessGlobals.empty())
2612 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2617void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2621 unsigned N = ExtendedGlobals.
size();
2631 if (Mapping.Scale > 3)
2632 AllGlobals->setAlignment(
Align(1ULL << Mapping.Scale));
2637 ConstantInt::get(IntptrTy,
N)});
2643 IrbDtor.CreateCall(AsanUnregisterGlobals,
2645 ConstantInt::get(IntptrTy,
N)});
2654void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2659 if (CompileKernel) {
2660 for (
auto &GA :
M.aliases()) {
2662 AliasedGlobalExclusions.
insert(GV);
2667 for (
auto &
G :
M.globals()) {
2668 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2672 size_t n = GlobalsToChange.
size();
2673 auto &
DL =
M.getDataLayout();
2687 IntptrTy, IntptrTy, IntptrTy);
2691 for (
size_t i = 0; i < n; i++) {
2695 if (
G->hasSanitizerMetadata())
2696 MD =
G->getSanitizerMetadata();
2701 std::string NameForGlobal =
G->getName().str();
2706 Type *Ty =
G->getValueType();
2707 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2720 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2721 G->getThreadLocalMode(),
G->getAddressSpace());
2731 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2734 if (Seq && Seq->isCString())
2735 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2742 G->replaceAllUsesWith(NewGlobal);
2744 G->eraseFromParent();
2745 NewGlobals[i] = NewGlobal;
2750 bool CanUsePrivateAliases =
2751 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2752 TargetTriple.isOSBinFormatWasm();
2753 if (CanUsePrivateAliases && UsePrivateAlias) {
2756 InstrumentedGlobal =
2763 }
else if (UseOdrIndicator) {
2766 auto *ODRIndicatorSym =
2775 ODRIndicatorSym->setAlignment(
Align(1));
2782 ConstantInt::get(IntptrTy, SizeInBytes),
2783 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2786 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2791 Initializers[i] = Initializer;
2797 for (
size_t i = 0; i < n; i++) {
2799 if (
G->getName().empty())
continue;
2804 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2811 }
else if (n == 0) {
2814 *CtorComdat = TargetTriple.isOSBinFormatELF();
2816 *CtorComdat =
false;
2817 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2818 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2819 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2820 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2822 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2828 createInitializerPoisonCalls();
2834ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2835 constexpr uint64_t kMaxRZ = 1 << 18;
2836 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2839 if (SizeInBytes <= MinRZ / 2) {
2843 RZ = MinRZ - SizeInBytes;
2846 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2849 if (SizeInBytes % MinRZ)
2850 RZ += MinRZ - (SizeInBytes % MinRZ);
2853 assert((RZ + SizeInBytes) % MinRZ == 0);
2858int ModuleAddressSanitizer::GetAsanVersion()
const {
2859 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2860 bool isAndroid =
M.getTargetTriple().isAndroid();
2864 Version += (LongSize == 32 && isAndroid);
2879bool ModuleAddressSanitizer::instrumentModule() {
2880 initializeCallbacks();
2888 if (CompileKernel) {
2893 std::string AsanVersion = std::to_string(GetAsanVersion());
2894 std::string VersionCheckName =
2896 std::tie(AsanCtorFunction, std::ignore) =
2899 {}, VersionCheckName);
2903 bool CtorComdat =
true;
2906 if (AsanCtorFunction) {
2907 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2908 instrumentGlobals(IRB, &CtorComdat);
2911 instrumentGlobals(IRB, &CtorComdat);
2920 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2921 if (AsanCtorFunction) {
2925 if (AsanDtorFunction) {
2930 if (AsanCtorFunction)
2932 if (AsanDtorFunction)
2943 for (
int Exp = 0;
Exp < 2;
Exp++) {
2944 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2945 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2946 const std::string ExpStr =
Exp ?
"exp_" :
"";
2947 const std::string EndingStr = Recover ?
"_noabort" :
"";
2957 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2958 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2959 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2962 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2966 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2967 Inserter.insertFunction(
2972 AccessSizeIndex++) {
2973 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2974 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2975 Inserter.insertFunction(
2979 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2980 Inserter.insertFunction(
2987 const std::string MemIntrinCallbackPrefix =
2991 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2992 PtrTy, PtrTy, PtrTy, IntptrTy);
2993 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2994 PtrTy, PtrTy, PtrTy, IntptrTy);
2996 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
3001 AsanHandleNoReturnFunc =
3004 AsanPtrCmpFunction =
3006 AsanPtrSubFunction =
3008 if (Mapping.InGlobal)
3009 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
3012 AMDGPUAddressShared =
3018bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
3026 if (
F.getName().contains(
" load]")) {
3036bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
3042 if (Mapping.InGlobal) {
3050 LocalDynamicShadow =
3051 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
3053 LocalDynamicShadow =
3057 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
3059 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
3064void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
3069 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
3073 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
3079 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
3081 for (
Value *Arg :
II->args()) {
3084 "non-static alloca arg to localescape");
3085 ProcessedAllocas[AI] =
false;
3094void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
3100 for (
Value *Operand : CatchPad->arg_operands())
3102 ProcessedAllocas[AI] =
false;
3108bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
3109 bool ShouldInstrument =
3113 return !ShouldInstrument;
3116bool AddressSanitizer::instrumentFunction(
Function &
F,
3119 bool FunctionModified =
false;
3122 if (
F.hasFnAttribute(Attribute::Naked))
3123 return FunctionModified;
3128 if (maybeInsertAsanInitAtFunctionEntry(
F))
3129 FunctionModified =
true;
3132 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
3134 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3135 return FunctionModified;
3139 initializeCallbacks(TLI);
3141 FunctionStateRAII CleanupObj(
this);
3143 RuntimeCallInserter RTCI(
F);
3145 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
3149 markEscapedLocalAllocas(
F);
3151 if (TargetTriple.isOSWindows())
3152 markCatchParametersAsUninteresting(
F);
3164 for (
auto &BB :
F) {
3166 TempsToInstrument.
clear();
3167 int NumInsnsPerBB = 0;
3168 for (
auto &Inst : BB) {
3169 if (LooksLikeCodeInBug11395(&Inst))
return false;
3176 if (!InterestingOperands.
empty()) {
3177 for (
auto &Operand : InterestingOperands) {
3179 Value *Ptr = Operand.getPtr();
3183 if (Operand.MaybeMask) {
3184 if (TempsToInstrument.
count(Ptr))
3187 if (!TempsToInstrument.
insert(Ptr).second)
3191 OperandsToInstrument.
push_back(Operand);
3198 PointerComparisonsOrSubtracts.
push_back(&Inst);
3206 TempsToInstrument.
clear();
3217 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3218 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
3219 (
unsigned)InstrumentationWithCallsThreshold);
3224 int NumInstrumented = 0;
3225 for (
auto &Operand : OperandsToInstrument) {
3226 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3227 instrumentMop(ObjSizeVis, Operand, UseCalls,
3228 F.getDataLayout(), RTCI);
3229 FunctionModified =
true;
3231 for (
auto *Inst : IntrinToInstrument) {
3232 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3233 instrumentMemIntrinsic(Inst, RTCI);
3234 FunctionModified =
true;
3237 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3238 bool ChangedStack = FSP.runOnFunction();
3242 for (
auto *CI : NoReturnCalls) {
3244 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3247 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3248 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3251 if (ChangedStack || !NoReturnCalls.empty())
3252 FunctionModified =
true;
3254 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3257 return FunctionModified;
3263bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3264 if (LongSize != 32)
return false;
3273void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
3277 const char *MallocNameTemplate =
3282 std::string Suffix =
itostr(Index);
3283 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3284 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3285 AsanStackFreeFunc[
Index] =
3290 if (ASan.UseAfterScope) {
3291 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3293 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3297 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3298 0xf3, 0xf5, 0xf8}) {
3299 std::ostringstream
Name;
3301 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3302 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3306 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3308 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3314 size_t Begin,
size_t End,
3316 Value *ShadowBase) {
3320 const size_t LargestStoreSizeInBytes =
3321 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3323 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3329 for (
size_t i = Begin; i < End;) {
3330 if (!ShadowMask[i]) {
3336 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3338 while (StoreSizeInBytes > End - i)
3339 StoreSizeInBytes /= 2;
3342 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3343 while (j <= StoreSizeInBytes / 2)
3344 StoreSizeInBytes /= 2;
3348 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3350 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3352 Val = (Val << 8) | ShadowBytes[i + j];
3355 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3361 i += StoreSizeInBytes;
3368 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3373 size_t Begin,
size_t End,
3376 size_t Done = Begin;
3377 for (
size_t i = Begin, j = Begin + 1; i < End; i =
j++) {
3378 if (!ShadowMask[i]) {
3382 uint8_t Val = ShadowBytes[i];
3383 if (!AsanSetShadowFunc[Val])
3387 for (;
j < End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3390 if (j - i >= ASan.MaxInlinePoisoningSize) {
3391 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3392 RTCI.createRuntimeCall(
3393 IRB, AsanSetShadowFunc[Val],
3394 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3395 ConstantInt::get(IntptrTy, j - i)});
3400 copyToShadowInline(ShadowMask, ShadowBytes,
Done, End, IRB, ShadowBase);
3408 for (
int i = 0;; i++, MaxSize *= 2)
3409 if (LocalStackSize <= MaxSize)
return i;
3413void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3415 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3423 if (Arg.hasByValAttr()) {
3424 Type *Ty = Arg.getParamByValType();
3426 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3430 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3433 Arg.replaceAllUsesWith(AI);
3435 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3436 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3444 Value *ValueIfFalse) {
3447 PHI->addIncoming(ValueIfFalse, CondBlock);
3449 PHI->addIncoming(ValueIfTrue, ThenBlock);
3453Value *FunctionStackPoisoner::createAllocaForLayout(
3462 nullptr,
"MyAlloca");
3471void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3474 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3479void FunctionStackPoisoner::processDynamicAllocas() {
3486 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3489 assert(ASan.isInterestingAlloca(*APC.AI));
3490 assert(!APC.AI->isStaticAlloca());
3493 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3500 createDynamicAllocasInitStorage();
3501 for (
auto &AI : DynamicAllocaVec)
3502 handleDynamicAllocaCall(AI);
3503 unpoisonDynamicAllocas();
3515 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3532 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3537 bool IsArgInitViaCast =
3542 Val == It->getPrevNode();
3543 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3547 if (IsArgInitViaCast)
3562 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3565 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3569 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3572 auto MetadataString =
3574 if (MetadataString->getString() ==
"alloca_name_altered")
3583void FunctionStackPoisoner::processStaticAllocas() {
3584 if (AllocaVec.
empty()) {
3589 int StackMallocIdx = -1;
3591 if (
auto SP =
F.getSubprogram())
3592 EntryDebugLocation =
3601 auto InsBeforeB = InsBefore->
getParent();
3602 assert(InsBeforeB == &
F.getEntryBlock());
3603 for (
auto *AI : StaticAllocasToMoveUp)
3614 ArgInitInst->moveBefore(InsBefore->
getIterator());
3617 if (LocalEscapeCall)
3625 ASan.getAllocaSizeInBytes(*AI),
3636 uint64_t Granularity = 1ULL << Mapping.Scale;
3637 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3643 for (
auto &
Desc : SVD)
3647 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3650 assert(ASan.isInterestingAlloca(*APC.AI));
3651 assert(APC.AI->isStaticAlloca());
3656 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3657 if (LifetimeLoc->getFile() == FnLoc->getFile())
3658 if (
unsigned Line = LifetimeLoc->getLine())
3659 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3665 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3667 bool DoStackMalloc =
3677 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3678 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3680 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3681 Value *StaticAlloca =
3682 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3684 Value *FakeStackPtr;
3685 Value *FakeStackInt;
3686 Value *LocalStackBase;
3687 Value *LocalStackBaseAlloca;
3690 if (DoStackMalloc) {
3691 LocalStackBaseAlloca =
3692 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3699 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3709 Value *FakeStackValue =
3710 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3711 ConstantInt::get(IntptrTy, LocalStackSize));
3713 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3714 Term, ConstantInt::get(IntptrTy, 0));
3722 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3723 ConstantInt::get(IntptrTy, LocalStackSize));
3726 Value *NoFakeStack =
3731 Value *AllocaValue =
3732 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3736 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3737 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3745 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3746 LocalStackBaseAlloca = LocalStackBase;
3751 for (
const auto &
Desc : SVD) {
3755 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3768 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3776 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3783 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3786 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3788 if (!StaticAllocaPoisonCallVec.empty()) {
3792 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3795 size_t Begin =
Desc.Offset /
L.Granularity;
3796 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3799 copyToShadow(ShadowAfterScope,
3800 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3806 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3809 if (
I->isLifetimeStartOrEnd())
3810 I->eraseFromParent();
3823 if (DoStackMalloc) {
3824 assert(StackMallocIdx >= 0);
3841 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3843 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3845 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3847 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3849 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3850 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3851 IRBPoison.CreateStore(
3853 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3856 RTCI.createRuntimeCall(
3857 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3858 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3862 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3864 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3869 for (
auto *AI : AllocaVec)
3877 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3878 RTCI.createRuntimeCall(
3879 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3880 {AddrArg, SizeArg});
3891void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3899 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3933 ConstantInt::get(IntptrTy,
Alignment.value()));
3936 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3947 if (
I->isLifetimeStartOrEnd())
3948 I->eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::list< unsigned > ClAddrSpaces("asan-instrument-address-spaces", cl::desc("Only instrument variables in the specified address spaces."), cl::Hidden, cl::CommaSeparated)
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
constexpr size_t kAccessSizeIndexShift
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
const char kAsanPoisonStackMemoryName[]
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isSupportedAddrspace(const Triple &TargetTriple, Value *Addr)
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static cl::opt< AsanDetectStackUseAfterReturnMode > ClUseAfterReturn("asan-use-after-return", cl::desc("Sets the mode of detection for stack-use-after-return."), cl::values(clEnumValN(AsanDetectStackUseAfterReturnMode::Never, "never", "Never detect stack use after return."), clEnumValN(AsanDetectStackUseAfterReturnMode::Runtime, "runtime", "Detect stack use after return if " "binary flag 'ASAN_OPTIONS=detect_stack_use_after_return' is set."), clEnumValN(AsanDetectStackUseAfterReturnMode::Always, "always", "Always detect stack use after return.")), cl::Hidden, cl::init(AsanDetectStackUseAfterReturnMode::Runtime))
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static const uintptr_t kCurrentStackFrameMagic
static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kPPC64_ShadowOffset64
static cl::opt< AsanCtorKind > ClConstructorKind("asan-constructor-kind", cl::desc("Sets the ASan constructor kind"), cl::values(clEnumValN(AsanCtorKind::None, "none", "No constructors"), clEnumValN(AsanCtorKind::Global, "global", "Use global constructors")), cl::init(AsanCtorKind::Global), cl::Hidden)
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
static const uint64_t kNetBSD_ShadowOffset64
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
static const uint64_t kWindowsShadowOffset32
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const char kAsanReportErrorTemplate[]
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
static StringRef getAllocaName(AllocaInst *AI)
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
static const uintptr_t kRetiredStackFrameMagic
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
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 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.
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)
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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.
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.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
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.