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."),
467STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
468STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
470 "Number of optimized accesses to global vars");
472 "Number of optimized accesses to stack vars");
481struct ShadowMapping {
492 bool IsAndroid = TargetTriple.
isAndroid();
495 bool IsMacOS = TargetTriple.
isMacOSX();
498 bool IsPS = TargetTriple.
isPS();
504 bool IsMIPSN32ABI = TargetTriple.
isABIN32();
505 bool IsMIPS32 = TargetTriple.
isMIPS32();
506 bool IsMIPS64 = TargetTriple.
isMIPS64();
507 bool IsArmOrThumb = TargetTriple.
isARM() || TargetTriple.
isThumb();
514 bool IsAMDGPU = TargetTriple.
isAMDGPU();
516 bool IsWasm = TargetTriple.
isWasm();
517 bool IsBPF = TargetTriple.
isBPF();
519 ShadowMapping Mapping;
526 if (LongSize == 32) {
529 else if (IsMIPSN32ABI)
555 else if (IsFreeBSD && IsAArch64)
557 else if (IsFreeBSD && !IsMIPS64) {
562 }
else if (IsNetBSD) {
569 else if (IsLinux && IsX86_64) {
575 }
else if (IsWindows && (IsX86_64 || IsAArch64)) {
581 else if (IsMacOS && IsAArch64)
585 else if (IsLoongArch64)
592 else if (IsHaiku && IsX86_64)
616 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
617 !IsRISCV64 && !IsLoongArch64 &&
618 !(Mapping.Offset & (Mapping.Offset - 1)) &&
620 Mapping.InGlobal =
ClWithIfunc && IsAndroid && IsArmOrThumb;
626 bool IsKasan, uint64_t *ShadowBase,
627 int *MappingScale,
bool *OrShadowOffset) {
629 *ShadowBase = Mapping.Offset;
630 *MappingScale = Mapping.Scale;
631 *OrShadowOffset = Mapping.OrShadowOffset;
652 if (!
F.getMemoryEffects()
654 .doesNotAccessMemory() &&
656 F.setMemoryEffects(
F.getMemoryEffects() |
664 F.setMemoryEffects(
F.getMemoryEffects() |
669 if (
A.hasAttribute(Attribute::WriteOnly)) {
670 A.removeAttr(Attribute::WriteOnly);
678 F.addFnAttr(Attribute::NoBuiltin);
699 return std::max(32U, 1U << MappingScale);
715class AsanFunctionInserter {
717 AsanFunctionInserter(
Module &M) :
M(
M) {}
719 template <
typename... ArgTypes>
720 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
721 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
734class RuntimeCallInserter {
736 bool TrackInsertedCalls =
false;
740 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
742 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
743 if (isScopedEHPersonality(Personality))
744 TrackInsertedCalls = true;
748 ~RuntimeCallInserter() {
749 if (InsertedCalls.
empty())
751 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
753 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
754 for (CallInst *CI : InsertedCalls) {
756 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
758 "Instruction doesn't belong to the expected Function!");
766 if (Colors.
size() != 1) {
768 "Instruction's BasicBlock is not monochromatic");
775 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
779 OB, CI->getIterator());
780 NewCall->copyMetadata(*CI);
781 CI->replaceAllUsesWith(NewCall);
782 CI->eraseFromParent();
787 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
789 const Twine &
Name =
"") {
792 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
793 if (TrackInsertedCalls)
794 InsertedCalls.push_back(Inst);
800struct AddressSanitizer {
801 AddressSanitizer(
Module &M,
const StackSafetyGlobalInfo *SSGI,
802 int InstrumentationWithCallsThreshold,
803 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
804 bool Recover =
false,
bool UseAfterScope =
false,
806 AsanDetectStackUseAfterReturnMode::Runtime)
815 InstrumentationWithCallsThreshold(
818 : InstrumentationWithCallsThreshold),
821 : MaxInlinePoisoningSize) {
822 C = &(
M.getContext());
823 DL = &
M.getDataLayout();
824 LongSize =
M.getDataLayout().getPointerSizeInBits();
825 IntptrTy = Type::getIntNTy(*
C, LongSize);
826 PtrTy = PointerType::getUnqual(*
C);
827 Int32Ty = Type::getInt32Ty(*
C);
828 TargetTriple =
M.getTargetTriple();
832 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
840 bool isInterestingAlloca(
const AllocaInst &AI);
842 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
844 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
845 const TargetTransformInfo *
TTI);
847 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
848 InterestingMemoryOperand &O,
bool UseCalls,
849 const DataLayout &
DL, RuntimeCallInserter &RTCI);
850 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
851 RuntimeCallInserter &RTCI);
853 Value *Addr, MaybeAlign Alignment,
854 uint32_t TypeStoreSize,
bool IsWrite,
855 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
856 RuntimeCallInserter &RTCI);
857 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
858 Instruction *InsertBefore,
Value *Addr,
859 uint32_t TypeStoreSize,
bool IsWrite,
860 Value *SizeArgument);
863 void instrumentUnusualSizeOrAlignment(Instruction *
I,
864 Instruction *InsertBefore,
Value *Addr,
865 TypeSize TypeStoreSize,
bool IsWrite,
866 Value *SizeArgument,
bool UseCalls,
868 RuntimeCallInserter &RTCI);
869 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
872 MaybeAlign Alignment,
unsigned Granularity,
873 Type *OpType,
bool IsWrite,
874 Value *SizeArgument,
bool UseCalls,
875 uint32_t Exp, RuntimeCallInserter &RTCI);
877 Value *ShadowValue, uint32_t TypeStoreSize);
879 bool IsWrite,
size_t AccessSizeIndex,
880 Value *SizeArgument, uint32_t Exp,
881 RuntimeCallInserter &RTCI);
882 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
884 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
885 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
886 const TargetTransformInfo *
TTI);
887 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
888 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
889 void markEscapedLocalAllocas(
Function &
F);
890 void markCatchParametersAsUninteresting(
Function &
F);
893 friend struct FunctionStackPoisoner;
895 void initializeCallbacks(
const TargetLibraryInfo *TLI);
897 bool LooksLikeCodeInBug11395(Instruction *
I);
898 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
899 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
900 TypeSize TypeStoreSize)
const;
903 struct FunctionStateRAII {
904 AddressSanitizer *
Pass;
906 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
908 "last pass forgot to clear cache");
912 ~FunctionStateRAII() {
913 Pass->LocalDynamicShadow =
nullptr;
914 Pass->ProcessedAllocas.clear();
919 AsanFunctionInserter Inserter;
921 const DataLayout *
DL;
931 ShadowMapping Mapping;
932 FunctionCallee AsanHandleNoReturnFunc;
933 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
941 FunctionCallee AsanErrorCallbackSized[2][2];
942 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
944 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
945 Value *LocalDynamicShadow =
nullptr;
946 const StackSafetyGlobalInfo *SSGI;
947 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
949 FunctionCallee AMDGPUAddressShared;
950 FunctionCallee AMDGPUAddressPrivate;
951 int InstrumentationWithCallsThreshold;
952 uint32_t MaxInlinePoisoningSize;
955class ModuleAddressSanitizer {
957 ModuleAddressSanitizer(
Module &M,
bool InsertVersionCheck,
958 bool CompileKernel =
false,
bool Recover =
false,
959 bool UseGlobalsGC =
true,
bool UseOdrIndicator =
true,
967 : InsertVersionCheck),
969 UseGlobalsGC(UseGlobalsGC &&
ClUseGlobalsGC && !this->CompileKernel),
984 UseCtorComdat(UseGlobalsGC &&
ClWithComdat && !this->CompileKernel),
985 DestructorKind(DestructorKind),
989 C = &(
M.getContext());
990 int LongSize =
M.getDataLayout().getPointerSizeInBits();
991 IntptrTy = Type::getIntNTy(*
C, LongSize);
992 PtrTy = PointerType::getUnqual(*
C);
993 TargetTriple =
M.getTargetTriple();
998 assert(this->DestructorKind != AsanDtorKind::Invalid);
1001 bool instrumentModule();
1004 void initializeCallbacks();
1006 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
1013 const std::string &UniqueModuleId);
1018 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
1022 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
1023 StringRef OriginalName);
1024 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
1025 StringRef InternalSuffix);
1028 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
1029 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
1030 bool ShouldUseMachOGlobalsSection()
const;
1031 StringRef getGlobalMetadataSection()
const;
1032 void poisonOneInitializer(
Function &GlobalInit);
1033 void createInitializerPoisonCalls();
1034 uint64_t getMinRedzoneSizeForGlobal()
const {
1038 int GetAsanVersion()
const;
1039 GlobalVariable *getOrCreateModuleName();
1042 AsanFunctionInserter Inserter;
1044 bool InsertVersionCheck;
1047 bool UsePrivateAlias;
1048 bool UseOdrIndicator;
1055 Triple TargetTriple;
1056 ShadowMapping Mapping;
1057 FunctionCallee AsanPoisonGlobals;
1058 FunctionCallee AsanUnpoisonGlobals;
1059 FunctionCallee AsanRegisterGlobals;
1060 FunctionCallee AsanUnregisterGlobals;
1061 FunctionCallee AsanRegisterImageGlobals;
1062 FunctionCallee AsanUnregisterImageGlobals;
1063 FunctionCallee AsanRegisterElfGlobals;
1064 FunctionCallee AsanUnregisterElfGlobals;
1066 Function *AsanCtorFunction =
nullptr;
1067 Function *AsanDtorFunction =
nullptr;
1068 GlobalVariable *ModuleName =
nullptr;
1080struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
1082 AddressSanitizer &ASan;
1083 RuntimeCallInserter &RTCI;
1088 ShadowMapping Mapping;
1092 SmallVector<Instruction *, 8> RetVec;
1096 FunctionCallee AsanSetShadowFunc[0x100] = {};
1097 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
1098 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
1101 struct AllocaPoisonCall {
1102 IntrinsicInst *InsBefore;
1112 AllocaInst *DynamicAllocaLayout =
nullptr;
1113 IntrinsicInst *LocalEscapeCall =
nullptr;
1115 bool HasInlineAsm =
false;
1116 bool HasReturnsTwiceCall =
false;
1119 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
1120 RuntimeCallInserter &RTCI)
1121 :
F(
F), ASan(ASan), RTCI(RTCI),
1123 IntptrTy(ASan.IntptrTy),
1125 Mapping(ASan.Mapping),
1133 copyArgsPassedByValToAllocas();
1138 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
1140 initializeCallbacks(*
F.getParent());
1142 processDynamicAllocas();
1143 processStaticAllocas();
1154 void copyArgsPassedByValToAllocas();
1159 void processStaticAllocas();
1160 void processDynamicAllocas();
1162 void createDynamicAllocasInitStorage();
1167 void visitReturnInst(ReturnInst &RI) {
1168 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
1175 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
1178 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
1180 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
1181 Value *SavedStack) {
1190 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
1196 RTCI.createRuntimeCall(
1197 IRB, AsanAllocasUnpoisonFunc,
1198 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
1202 void unpoisonDynamicAllocas() {
1203 for (Instruction *Ret : RetVec)
1204 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
1206 for (Instruction *StackRestoreInst : StackRestoreVec)
1207 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
1208 StackRestoreInst->getOperand(0));
1221 void handleDynamicAllocaCall(AllocaInst *AI);
1224 void visitAllocaInst(AllocaInst &AI) {
1226 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
1230 if (AllocaVec.
empty())
1246 void visitIntrinsicInst(IntrinsicInst &
II) {
1248 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
1249 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
1250 if (!ASan.UseAfterScope)
1252 if (!
II.isLifetimeStartOrEnd())
1257 if (!AI || !ASan.isInterestingAlloca(*AI))
1267 bool DoPoison = (
ID == Intrinsic::lifetime_end);
1268 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
1270 StaticAllocaPoisonCallVec.
push_back(APC);
1272 DynamicAllocaPoisonCallVec.
push_back(APC);
1275 void visitCallBase(CallBase &CB) {
1277 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1278 HasReturnsTwiceCall |= CI->canReturnTwice();
1283 void initializeCallbacks(
Module &M);
1288 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1290 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1293 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1294 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1299 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1302 Instruction *ThenTerm,
Value *ValueIfFalse);
1309 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1310 OS, MapClassName2PassName);
1312 if (Options.CompileKernel)
1314 if (Options.UseAfterScope)
1315 OS <<
"use-after-scope";
1323 : Options(Options), UseGlobalGC(UseGlobalGC),
1324 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1325 ConstructorKind(ConstructorKind) {}
1334 ModuleAddressSanitizer ModuleSanitizer(
1335 M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
1336 UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
1348 if (
F.getName().starts_with(
"__asan_"))
1350 if (
F.isPresplitCoroutine())
1352 AddressSanitizer FunctionSanitizer(
1353 M, SSGI, Options.InstrumentationWithCallsThreshold,
1354 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1355 Options.UseAfterScope, Options.UseAfterReturn);
1358 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1360 Modified |= ModuleSanitizer.instrumentModule();
1381 if (
G->getName().starts_with(
"llvm.") ||
1383 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1385 G->getName().starts_with(
"__llvm_rtti_proxy"))
1401 if (AddrSpace == 3 || AddrSpace == 5)
1416 return AddrSpace == 0;
1420 if (TargetTriple.isOSDarwin() &&
1424 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1427 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1428 if (Mapping.Offset == 0)
return Shadow;
1431 if (LocalDynamicShadow)
1432 ShadowBase = LocalDynamicShadow;
1434 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1435 if (Mapping.OrShadowOffset)
1436 return IRB.
CreateOr(Shadow, ShadowBase);
1438 return IRB.
CreateAdd(Shadow, ShadowBase);
1443 RuntimeCallInserter &RTCI) {
1446 RTCI.createRuntimeCall(
1452 RTCI.createRuntimeCall(
1458 MI->eraseFromParent();
1462bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1463 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1466 return It->getSecond();
1468 bool IsInteresting =
1479 !(SSGI && SSGI->
isSafe(AI)));
1481 It->second = IsInteresting;
1482 return IsInteresting;
1512void AddressSanitizer::getInterestingMemoryOperands(
1516 if (LocalDynamicShadow ==
I)
1522 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1523 LI->getType(), LI->getAlign());
1528 SI->getValueOperand()->getType(),
SI->getAlign());
1532 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1533 RMW->getValOperand()->getType(), std::nullopt);
1537 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1538 XCHG->getCompareOperand()->getType(),
1541 switch (CI->getIntrinsicID()) {
1542 case Intrinsic::masked_load:
1543 case Intrinsic::masked_store:
1544 case Intrinsic::masked_gather:
1545 case Intrinsic::masked_scatter: {
1546 bool IsWrite = CI->getType()->isVoidTy();
1548 unsigned OpOffset = IsWrite ? 1 : 0;
1552 auto BasePtr = CI->getOperand(OpOffset);
1553 if (ignoreAccess(
I, BasePtr))
1555 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1557 Value *
Mask = CI->getOperand(1 + OpOffset);
1558 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1561 case Intrinsic::masked_expandload:
1562 case Intrinsic::masked_compressstore: {
1563 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1564 unsigned OpOffset = IsWrite ? 1 : 0;
1567 auto BasePtr = CI->getOperand(OpOffset);
1568 if (ignoreAccess(
I, BasePtr))
1571 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1574 Value *
Mask = CI->getOperand(1 + OpOffset);
1577 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1578 Value *EVL =
IB.CreateAddReduce(ExtMask);
1579 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1580 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1584 case Intrinsic::vp_load:
1585 case Intrinsic::vp_store:
1586 case Intrinsic::experimental_vp_strided_load:
1587 case Intrinsic::experimental_vp_strided_store: {
1589 unsigned IID = CI->getIntrinsicID();
1590 bool IsWrite = CI->getType()->isVoidTy();
1593 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1594 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1596 Value *Stride =
nullptr;
1597 if (IID == Intrinsic::experimental_vp_strided_store ||
1598 IID == Intrinsic::experimental_vp_strided_load) {
1599 Stride = VPI->getOperand(PtrOpNo + 1);
1603 unsigned PointerAlign =
Alignment.valueOrOne().value();
1608 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1609 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1613 case Intrinsic::vp_gather:
1614 case Intrinsic::vp_scatter: {
1616 unsigned IID = CI->getIntrinsicID();
1617 bool IsWrite = IID == Intrinsic::vp_scatter;
1620 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1621 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1623 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1624 VPI->getMaskParam(),
1625 VPI->getVectorLengthParam());
1631 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1635 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1637 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1639 Type *Ty = CI->getParamByValType(ArgNo);
1655 if (!Cmp->isRelational())
1669 if (BO->getOpcode() != Instruction::Sub)
1682 if (!
G->hasInitializer())
1685 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1692 Type *Ty = V->getType();
1693 if (Ty->isPtrOrPtrVectorTy())
1699bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1701 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1716 "invalid vector pointer pair instrumentation operands");
1717 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1718 Index != NumElements; ++Index) {
1719 Value *ScalarParam[2] = {
1726 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1733 RTCI.createRuntimeCall(IRB,
F, Param);
1740 TypeSize TypeStoreSize,
bool IsWrite,
1741 Value *SizeArgument,
bool UseCalls,
1742 uint32_t Exp, RuntimeCallInserter &RTCI) {
1747 switch (FixedSize) {
1753 if (!Alignment || *Alignment >= Granularity ||
1754 *Alignment >= FixedSize / 8)
1755 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1756 FixedSize, IsWrite,
nullptr, UseCalls,
1760 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1761 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1764void AddressSanitizer::instrumentMaskedLoadOrStore(
1767 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1768 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1769 RuntimeCallInserter &RTCI) {
1771 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1772 auto Zero = ConstantInt::get(IntptrTy, 0);
1780 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1782 IB.SetInsertPoint(LoopInsertBefore);
1784 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1787 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1788 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1790 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1795 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1799 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1800 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1801 if (MaskElemC->isZero())
1807 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1808 MaskElem, &*IRB.GetInsertPoint(), false);
1809 IRB.SetInsertPoint(ThenTerm);
1812 Value *InstrumentedAddress;
1815 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1816 "Expected vector of pointer.");
1817 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1818 }
else if (Stride) {
1825 Alignment, Granularity, ElemTypeSize, IsWrite,
1826 SizeArgument, UseCalls, Exp, RTCI);
1833 RuntimeCallInserter &RTCI) {
1834 Value *Addr =
O.getPtr();
1854 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1855 NumOptimizedAccessesToGlobalVar++;
1863 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1864 NumOptimizedAccessesToStackVar++;
1870 NumInstrumentedWrites++;
1872 NumInstrumentedReads++;
1874 if (
O.MaybeByteOffset) {
1879 if (TargetTriple.isRISCV()) {
1884 static_cast<unsigned>(LongSize)) {
1893 unsigned Granularity = 1 << Mapping.Scale;
1895 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1896 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1897 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1898 UseCalls, Exp, RTCI);
1901 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1902 UseCalls, Exp, RTCI);
1907 Value *Addr,
bool IsWrite,
1908 size_t AccessSizeIndex,
1909 Value *SizeArgument,
1911 RuntimeCallInserter &RTCI) {
1917 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1918 {Addr, SizeArgument});
1920 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1921 {Addr, SizeArgument, ExpVal});
1924 Call = RTCI.createRuntimeCall(
1925 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1927 Call = RTCI.createRuntimeCall(
1928 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1937 uint32_t TypeStoreSize) {
1938 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1940 Value *LastAccessedByte =
1941 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1943 if (TypeStoreSize / 8 > 1)
1945 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1948 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1953Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1955 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1962 return InsertBefore;
1967 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1969 Value *AddrSpaceZeroLanding =
1972 return InsertBefore;
1987 Trm->getParent()->setName(
"asan.report");
1998void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
2001 uint32_t TypeStoreSize,
bool IsWrite,
2002 Value *SizeArgument,
bool UseCalls,
2004 RuntimeCallInserter &RTCI) {
2005 if (TargetTriple.isAMDGPU()) {
2006 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
2007 TypeStoreSize, IsWrite, SizeArgument);
2016 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
2019 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
2026 RTCI.createRuntimeCall(
2027 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
2029 RTCI.createRuntimeCall(
2030 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
2031 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
2038 Value *ShadowPtr = memToShadow(AddrLong, IRB);
2040 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
2045 size_t Granularity = 1ULL << Mapping.Scale;
2048 bool GenSlowPath = (
ClAlwaysSlowPath || (TypeStoreSize < 8 * Granularity));
2050 if (TargetTriple.isAMDGCN()) {
2052 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2055 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
2056 }
else if (GenSlowPath) {
2063 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
2078 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
2087void AddressSanitizer::instrumentUnusualSizeOrAlignment(
2089 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
2090 uint32_t Exp, RuntimeCallInserter &RTCI) {
2098 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
2101 RTCI.createRuntimeCall(
2102 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
2116void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
2122 Value *ModuleNameAddr =
2130 for (
auto &BB : GlobalInit)
2142void ModuleAddressSanitizer::createInitializerPoisonCalls() {
2162 poisonOneInitializer(*
F);
2168ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
2173 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
2185bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
2186 Type *Ty =
G->getValueType();
2189 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
2191 if (!Ty->
isSized())
return false;
2192 if (!
G->hasInitializer())
return false;
2199 if (
G->isThreadLocal())
return false;
2201 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
2207 if (!TargetTriple.isOSBinFormatCOFF()) {
2208 if (!
G->hasExactDefinition() ||
G->hasComdat())
2212 if (
G->isInterposable())
2216 if (
G->hasAvailableExternallyLinkage())
2223 switch (
C->getSelectionKind()) {
2234 if (
G->hasSection()) {
2244 if (Section ==
"llvm.metadata")
return false;
2251 if (
Section.starts_with(
".preinit_array") ||
2252 Section.starts_with(
".init_array") ||
2253 Section.starts_with(
".fini_array")) {
2259 if (TargetTriple.isOSBinFormatELF()) {
2273 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2274 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2279 if (TargetTriple.isOSBinFormatMachO()) {
2281 unsigned TAA = 0, StubSize = 0;
2284 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2289 if (ParsedSegment ==
"__OBJC" ||
2290 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2302 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2315 if (CompileKernel) {
2318 if (
G->getName().starts_with(
"__"))
2328bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2329 if (!TargetTriple.isOSBinFormatMachO())
2332 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2334 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2336 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2338 if (TargetTriple.isDriverKit())
2340 if (TargetTriple.isXROS())
2346StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2347 switch (TargetTriple.getObjectFormat()) {
2357 "ModuleAddressSanitizer not implemented for object file format");
2364void ModuleAddressSanitizer::initializeCallbacks() {
2370 AsanUnpoisonGlobals =
2374 AsanRegisterGlobals = Inserter.insertFunction(
2376 AsanUnregisterGlobals = Inserter.insertFunction(
2381 AsanRegisterImageGlobals = Inserter.insertFunction(
2383 AsanUnregisterImageGlobals = Inserter.insertFunction(
2386 AsanRegisterElfGlobals =
2388 IntptrTy, IntptrTy, IntptrTy);
2389 AsanUnregisterElfGlobals =
2391 IntptrTy, IntptrTy, IntptrTy);
2396void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2401 if (!
G->hasName()) {
2405 G->setName(
genName(
"anon_global"));
2408 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2409 std::string
Name = std::string(
G->getName());
2410 Name += InternalSuffix;
2411 C =
M.getOrInsertComdat(Name);
2413 C =
M.getOrInsertComdat(
G->getName());
2419 if (TargetTriple.isOSBinFormatCOFF()) {
2421 if (
G->hasPrivateLinkage())
2434ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2436 auto Linkage = TargetTriple.isOSBinFormatMachO()
2442 Metadata->setSection(getGlobalMetadataSection());
2449Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2453 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2461void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2465 auto &
DL =
M.getDataLayout();
2468 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2469 Constant *Initializer = MetadataInitializers[i];
2473 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2479 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2481 "global metadata will not be padded appropriately");
2484 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2489 if (!MetadataGlobals.empty())
2493void ModuleAddressSanitizer::instrumentGlobalsELF(
2496 const std::string &UniqueModuleId) {
2503 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2506 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2509 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2511 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2514 if (UseComdatForGlobalsGC)
2515 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2520 if (!MetadataGlobals.empty())
2537 "__start_" + getGlobalMetadataSection());
2541 "__stop_" + getGlobalMetadataSection());
2555 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2562void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2573 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2574 Constant *Initializer = MetadataInitializers[i];
2580 auto LivenessBinder =
2585 Twine(
"__asan_binder_") +
G->getName());
2586 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2587 LivenessGlobals[i] = Liveness;
2594 if (!LivenessGlobals.empty())
2616 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2621void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2625 unsigned N = ExtendedGlobals.
size();
2635 if (Mapping.Scale > 3)
2636 AllGlobals->setAlignment(
Align(1ULL << Mapping.Scale));
2641 ConstantInt::get(IntptrTy,
N)});
2647 IrbDtor.CreateCall(AsanUnregisterGlobals,
2649 ConstantInt::get(IntptrTy,
N)});
2658void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2663 if (CompileKernel) {
2664 for (
auto &GA :
M.aliases()) {
2666 AliasedGlobalExclusions.
insert(GV);
2671 for (
auto &
G :
M.globals()) {
2672 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2676 size_t n = GlobalsToChange.
size();
2677 auto &
DL =
M.getDataLayout();
2691 IntptrTy, IntptrTy, IntptrTy);
2695 for (
size_t i = 0; i < n; i++) {
2699 if (
G->hasSanitizerMetadata())
2700 MD =
G->getSanitizerMetadata();
2705 std::string NameForGlobal =
G->getName().str();
2710 Type *Ty =
G->getValueType();
2711 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2724 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2725 G->getThreadLocalMode(),
G->getAddressSpace());
2735 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2738 if (Seq && Seq->isCString())
2739 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2746 G->replaceAllUsesWith(NewGlobal);
2748 G->eraseFromParent();
2749 NewGlobals[i] = NewGlobal;
2754 bool CanUsePrivateAliases =
2755 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2756 TargetTriple.isOSBinFormatWasm();
2757 if (CanUsePrivateAliases && UsePrivateAlias) {
2760 InstrumentedGlobal =
2767 }
else if (UseOdrIndicator) {
2770 auto *ODRIndicatorSym =
2779 ODRIndicatorSym->setAlignment(
Align(1));
2786 ConstantInt::get(IntptrTy, SizeInBytes),
2787 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2790 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2795 Initializers[i] = Initializer;
2801 for (
size_t i = 0; i < n; i++) {
2803 if (
G->getName().empty())
continue;
2808 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2815 }
else if (n == 0) {
2818 *CtorComdat = TargetTriple.isOSBinFormatELF();
2820 *CtorComdat =
false;
2821 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2822 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2823 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2824 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2826 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2832 createInitializerPoisonCalls();
2838ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2839 constexpr uint64_t kMaxRZ = 1 << 18;
2840 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2843 if (SizeInBytes <= MinRZ / 2) {
2847 RZ = MinRZ - SizeInBytes;
2850 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2853 if (SizeInBytes % MinRZ)
2854 RZ += MinRZ - (SizeInBytes % MinRZ);
2857 assert((RZ + SizeInBytes) % MinRZ == 0);
2862int ModuleAddressSanitizer::GetAsanVersion()
const {
2863 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2864 bool isAndroid =
M.getTargetTriple().isAndroid();
2868 Version += (LongSize == 32 && isAndroid);
2883bool ModuleAddressSanitizer::instrumentModule() {
2884 initializeCallbacks();
2892 if (CompileKernel) {
2897 std::string AsanVersion = std::to_string(GetAsanVersion());
2898 std::string VersionCheckName =
2900 std::tie(AsanCtorFunction, std::ignore) =
2903 {}, VersionCheckName);
2907 bool CtorComdat =
true;
2910 if (AsanCtorFunction) {
2911 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2912 instrumentGlobals(IRB, &CtorComdat);
2915 instrumentGlobals(IRB, &CtorComdat);
2924 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2925 if (AsanCtorFunction) {
2929 if (AsanDtorFunction) {
2934 if (AsanCtorFunction)
2936 if (AsanDtorFunction)
2947 for (
int Exp = 0;
Exp < 2;
Exp++) {
2948 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2949 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2950 const std::string ExpStr =
Exp ?
"exp_" :
"";
2951 const std::string EndingStr = Recover ?
"_noabort" :
"";
2961 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2962 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2963 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2966 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2970 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2971 Inserter.insertFunction(
2976 AccessSizeIndex++) {
2977 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2978 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2979 Inserter.insertFunction(
2983 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2984 Inserter.insertFunction(
2991 const std::string MemIntrinCallbackPrefix =
2995 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2996 PtrTy, PtrTy, PtrTy, IntptrTy);
2997 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2998 PtrTy, PtrTy, PtrTy, IntptrTy);
3000 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
3005 AsanHandleNoReturnFunc =
3008 AsanPtrCmpFunction =
3010 AsanPtrSubFunction =
3012 if (Mapping.InGlobal)
3013 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
3016 AMDGPUAddressShared =
3022bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
3030 if (
F.getName().contains(
" load]")) {
3040bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
3046 if (Mapping.InGlobal) {
3054 LocalDynamicShadow =
3055 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
3057 LocalDynamicShadow =
3061 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
3063 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
3068void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
3073 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
3077 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
3083 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
3085 for (
Value *Arg :
II->args()) {
3088 "non-static alloca arg to localescape");
3089 ProcessedAllocas[AI] =
false;
3098void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
3104 for (
Value *Operand : CatchPad->arg_operands())
3106 ProcessedAllocas[AI] =
false;
3112bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
3113 bool ShouldInstrument =
3117 return !ShouldInstrument;
3120bool AddressSanitizer::instrumentFunction(
Function &
F,
3123 bool FunctionModified =
false;
3126 if (
F.hasFnAttribute(Attribute::Naked))
3127 return FunctionModified;
3132 if (maybeInsertAsanInitAtFunctionEntry(
F))
3133 FunctionModified =
true;
3136 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
3138 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
3139 return FunctionModified;
3143 initializeCallbacks(TLI);
3145 FunctionStateRAII CleanupObj(
this);
3147 RuntimeCallInserter RTCI(
F);
3149 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
3153 markEscapedLocalAllocas(
F);
3155 if (TargetTriple.isOSWindows())
3156 markCatchParametersAsUninteresting(
F);
3168 for (
auto &BB :
F) {
3170 TempsToInstrument.
clear();
3171 int NumInsnsPerBB = 0;
3172 for (
auto &Inst : BB) {
3173 if (LooksLikeCodeInBug11395(&Inst))
return false;
3180 if (!InterestingOperands.
empty()) {
3181 for (
auto &Operand : InterestingOperands) {
3183 Value *Ptr = Operand.getPtr();
3187 if (Operand.MaybeMask) {
3188 if (TempsToInstrument.
count(Ptr))
3191 if (!TempsToInstrument.
insert(Ptr).second)
3195 OperandsToInstrument.
push_back(Operand);
3202 PointerComparisonsOrSubtracts.
push_back(&Inst);
3210 TempsToInstrument.
clear();
3221 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
3222 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
3223 (
unsigned)InstrumentationWithCallsThreshold);
3228 int NumInstrumented = 0;
3229 for (
auto &Operand : OperandsToInstrument) {
3230 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3231 instrumentMop(ObjSizeVis, Operand, UseCalls,
3232 F.getDataLayout(), RTCI);
3233 FunctionModified =
true;
3235 for (
auto *Inst : IntrinToInstrument) {
3236 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
3237 instrumentMemIntrinsic(Inst, RTCI);
3238 FunctionModified =
true;
3241 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3242 bool ChangedStack = FSP.runOnFunction();
3246 for (
auto *CI : NoReturnCalls) {
3248 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3251 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3252 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3255 if (ChangedStack || !NoReturnCalls.empty())
3256 FunctionModified =
true;
3258 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3261 return FunctionModified;
3267bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3268 if (LongSize != 32)
return false;
3277void FunctionStackPoisoner::initializeCallbacks(
Module &) {
3281 const char *MallocNameTemplate =
3286 std::string Suffix =
itostr(Index);
3287 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3288 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3289 AsanStackFreeFunc[
Index] =
3294 if (ASan.UseAfterScope) {
3295 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3297 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3301 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3302 0xf3, 0xf5, 0xf8}) {
3303 std::ostringstream
Name;
3305 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3306 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3310 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3312 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3318 size_t Begin,
size_t End,
3320 Value *ShadowBase) {
3324 const size_t LargestStoreSizeInBytes =
3325 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3327 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3333 for (
size_t i = Begin; i < End;) {
3334 if (!ShadowMask[i]) {
3340 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3342 while (StoreSizeInBytes > End - i)
3343 StoreSizeInBytes /= 2;
3346 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3347 while (j <= StoreSizeInBytes / 2)
3348 StoreSizeInBytes /= 2;
3352 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3354 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3356 Val = (Val << 8) | ShadowBytes[i + j];
3359 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3365 i += StoreSizeInBytes;
3372 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3377 size_t Begin,
size_t End,
3380 size_t Done = Begin;
3381 for (
size_t i = Begin, j = Begin + 1; i < End; i =
j++) {
3382 if (!ShadowMask[i]) {
3386 uint8_t Val = ShadowBytes[i];
3387 if (!AsanSetShadowFunc[Val])
3391 for (;
j < End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3394 if (j - i >= ASan.MaxInlinePoisoningSize) {
3395 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3396 RTCI.createRuntimeCall(
3397 IRB, AsanSetShadowFunc[Val],
3398 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3399 ConstantInt::get(IntptrTy, j - i)});
3404 copyToShadowInline(ShadowMask, ShadowBytes,
Done, End, IRB, ShadowBase);
3412 for (
int i = 0;; i++, MaxSize *= 2)
3413 if (LocalStackSize <= MaxSize)
return i;
3417void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3419 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3427 if (Arg.hasByValAttr()) {
3428 Type *Ty = Arg.getParamByValType();
3430 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3434 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3437 Arg.replaceAllUsesWith(AI);
3439 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3440 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3448 Value *ValueIfFalse) {
3451 PHI->addIncoming(ValueIfFalse, CondBlock);
3453 PHI->addIncoming(ValueIfTrue, ThenBlock);
3457Value *FunctionStackPoisoner::createAllocaForLayout(
3466 nullptr,
"MyAlloca");
3475void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3478 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3483void FunctionStackPoisoner::processDynamicAllocas() {
3490 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3493 assert(ASan.isInterestingAlloca(*APC.AI));
3494 assert(!APC.AI->isStaticAlloca());
3497 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3504 createDynamicAllocasInitStorage();
3505 for (
auto &AI : DynamicAllocaVec)
3506 handleDynamicAllocaCall(AI);
3507 unpoisonDynamicAllocas();
3519 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3536 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3541 bool IsArgInitViaCast =
3546 Val == It->getPrevNode();
3547 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3551 if (IsArgInitViaCast)
3566 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3569 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3573 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3576 auto MetadataString =
3578 if (MetadataString->getString() ==
"alloca_name_altered")
3587void FunctionStackPoisoner::processStaticAllocas() {
3588 if (AllocaVec.
empty()) {
3593 int StackMallocIdx = -1;
3595 if (
auto SP =
F.getSubprogram())
3596 EntryDebugLocation =
3605 auto InsBeforeB = InsBefore->
getParent();
3606 assert(InsBeforeB == &
F.getEntryBlock());
3607 for (
auto *AI : StaticAllocasToMoveUp)
3618 ArgInitInst->moveBefore(InsBefore->
getIterator());
3621 if (LocalEscapeCall)
3629 ASan.getAllocaSizeInBytes(*AI),
3640 uint64_t Granularity = 1ULL << Mapping.Scale;
3641 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3647 for (
auto &
Desc : SVD)
3651 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3654 assert(ASan.isInterestingAlloca(*APC.AI));
3655 assert(APC.AI->isStaticAlloca());
3660 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3661 if (LifetimeLoc->getFile() == FnLoc->getFile())
3662 if (
unsigned Line = LifetimeLoc->getLine())
3663 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3669 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3671 bool DoStackMalloc =
3681 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3682 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3684 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3685 Value *StaticAlloca =
3686 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3688 Value *FakeStackPtr;
3689 Value *FakeStackInt;
3690 Value *LocalStackBase;
3691 Value *LocalStackBaseAlloca;
3694 if (DoStackMalloc) {
3695 LocalStackBaseAlloca =
3696 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3703 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3713 Value *FakeStackValue =
3714 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3715 ConstantInt::get(IntptrTy, LocalStackSize));
3717 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3718 Term, ConstantInt::get(IntptrTy, 0));
3726 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3727 ConstantInt::get(IntptrTy, LocalStackSize));
3730 Value *NoFakeStack =
3735 Value *AllocaValue =
3736 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3740 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3741 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3749 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3750 LocalStackBaseAlloca = LocalStackBase;
3755 for (
const auto &
Desc : SVD) {
3759 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3772 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3780 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3787 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3790 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3792 if (!StaticAllocaPoisonCallVec.empty()) {
3796 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3799 size_t Begin =
Desc.Offset /
L.Granularity;
3800 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3803 copyToShadow(ShadowAfterScope,
3804 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3810 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3813 if (
I->isLifetimeStartOrEnd())
3814 I->eraseFromParent();
3827 if (DoStackMalloc) {
3828 assert(StackMallocIdx >= 0);
3845 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3847 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3849 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3851 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3853 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3854 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3855 IRBPoison.CreateStore(
3857 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3860 RTCI.createRuntimeCall(
3861 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3862 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3866 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3868 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3873 for (
auto *AI : AllocaVec)
3881 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3882 RTCI.createRuntimeCall(
3883 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3884 {AddrArg, SizeArg});
3895void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3903 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3937 ConstantInt::get(IntptrTy,
Alignment.value()));
3940 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3951 if (
I->isLifetimeStartOrEnd())
3952 I->eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > ClUseStackSafety("stack-tagging-use-stack-safety", cl::Hidden, cl::init(true), cl::desc("Use Stack Safety analysis results"))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void findStoresToUninstrumentedArgAllocas(AddressSanitizer &ASan, Instruction &InsBefore, SmallVectorImpl< Instruction * > &InitInsts)
Collect instructions in the entry block after InsBefore which initialize permanent storage for a func...
static cl::opt< bool > ClUseStackSafety("asan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"))
static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I, Instruction *InsertBefore, Value *Addr, MaybeAlign Alignment, unsigned Granularity, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp, RuntimeCallInserter &RTCI)
static const uint64_t kDefaultShadowScale
const char kAMDGPUUnreachableName[]
constexpr size_t kAccessSizeIndexMask
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClUsePrivateAlias("asan-use-private-alias", cl::desc("Use private aliases for global variables"), cl::Hidden, cl::init(true))
static const uint64_t kPS_ShadowOffset64
static const uint64_t kFreeBSD_ShadowOffset32
constexpr size_t kIsWriteShift
static const uint64_t kSmallX86_64ShadowOffsetAlignMask
static bool isInterestingPointerSubtraction(Instruction *I)
const char kAMDGPUAddressSharedName[]
const char kAsanStackFreeNameTemplate[]
constexpr size_t kCompileKernelMask
static cl::opt< bool > ClForceDynamicShadow("asan-force-dynamic-shadow", cl::desc("Load shadow address into a local variable for each function"), cl::Hidden, cl::init(false))
const char kAsanOptionDetectUseAfterReturn[]
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static const uint64_t kRISCV64_ShadowOffset64
static cl::opt< bool > ClInsertVersionCheck("asan-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
const char kAsanSetShadowPrefix[]
static cl::opt< AsanDtorKind > ClOverrideDestructorKind("asan-destructor-kind", cl::desc("Sets the ASan destructor kind. The default is to use the value " "provided to the pass constructor"), cl::values(clEnumValN(AsanDtorKind::None, "none", "No destructors"), clEnumValN(AsanDtorKind::Global, "global", "Use global destructors")), cl::init(AsanDtorKind::Invalid), cl::Hidden)
static Twine genName(StringRef suffix)
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static uint64_t GetCtorAndDtorPriority(Triple &TargetTriple)
const char kAsanStackMallocNameTemplate[]
static cl::opt< bool > ClInstrumentByval("asan-instrument-byval", cl::desc("instrument byval call arguments"), cl::Hidden, cl::init(true))
const char kAsanInitName[]
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClRedzoneByvalArgs("asan-redzone-byval-args", cl::desc("Create redzones for byval " "arguments (extra copy " "required)"), cl::Hidden, cl::init(true))
static bool isPointerPairOperand(Value *V, Type *IntptrTy)
static const uint64_t kWindowsShadowOffset64
const char kAsanGenPrefix[]
constexpr size_t kIsWriteMask
static uint64_t getRedzoneSizeForScale(int MappingScale)
static const uint64_t kDefaultShadowOffset64
static cl::opt< bool > ClOptimizeCallbacks("asan-optimize-callbacks", cl::desc("Optimize callbacks"), cl::Hidden, cl::init(false))
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(true))
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static cl::opt< int > ClShadowAddrSpace("asan-shadow-addr-space", cl::desc("Address space for pointers to the shadow map"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClInvalidPointerCmp("asan-detect-invalid-pointer-cmp", cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInvalidPointerSub("asan-detect-invalid-pointer-sub", cl::desc("Instrument - operations with pointer operands"), cl::Hidden, cl::init(false))
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static cl::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
static cl::opt< int > ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
static cl::opt< bool > ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, cl::init(false))
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool isPointerOperand(Value *I, User *U)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file defines the SmallPtrSet class.
This file defines the 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.