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";
197STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
198STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
200 "Number of optimized accesses to global vars");
202 "Number of optimized accesses to stack vars");
211struct ShadowMapping {
221 const Triple &TargetTriple,
int LongSize,
223 bool IsAndroid = TargetTriple.
isAndroid();
226 bool IsMacOS = TargetTriple.
isMacOSX();
229 bool IsPS = TargetTriple.
isPS();
235 bool IsMIPSN32ABI = TargetTriple.
isABIN32();
236 bool IsMIPS32 = TargetTriple.
isMIPS32();
237 bool IsMIPS64 = TargetTriple.
isMIPS64();
238 bool IsArmOrThumb = TargetTriple.
isARM() || TargetTriple.
isThumb();
245 bool IsAMDGPU = TargetTriple.
isAMDGPU();
247 bool IsWasm = TargetTriple.
isWasm();
248 bool IsBPF = TargetTriple.
isBPF();
250 ShadowMapping Mapping;
254 if (LongSize == 32) {
257 else if (IsMIPSN32ABI)
283 else if (IsFreeBSD && IsAArch64)
285 else if (IsFreeBSD && !IsMIPS64) {
290 }
else if (IsNetBSD) {
297 else if (IsLinux && IsX86_64) {
303 }
else if (IsWindows && (IsX86_64 || IsAArch64)) {
309 else if (IsMacOS && IsAArch64)
313 else if (IsLoongArch64)
320 else if (IsHaiku && IsX86_64)
331 if (Opts.asan_force_dynamic_shadow) {
335 if (Opts.asan_mapping_offset) {
336 Mapping.Offset = *Opts.asan_mapping_offset;
344 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
345 !IsRISCV64 && !IsLoongArch64 &&
346 !(Mapping.Offset & (Mapping.Offset - 1)) &&
348 Mapping.InGlobal = Opts.asan_with_ifunc && IsAndroid && IsArmOrThumb;
354 bool IsKasan, uint64_t *ShadowBase,
355 int *MappingScale,
bool *OrShadowOffset) {
356 auto Mapping =
getShadowMapping(InstrumentationOptions::Global, TargetTriple,
358 *ShadowBase = Mapping.Offset;
359 *MappingScale = Mapping.Scale;
360 *OrShadowOffset = Mapping.OrShadowOffset;
381 if (!
F.getMemoryEffects()
383 .doesNotAccessMemory() &&
385 F.setMemoryEffects(
F.getMemoryEffects() |
393 F.setMemoryEffects(
F.getMemoryEffects() |
398 if (
A.hasAttribute(Attribute::WriteOnly)) {
399 A.removeAttr(Attribute::WriteOnly);
407 F.addFnAttr(Attribute::NoBuiltin);
428 return std::max(32U, 1U << MappingScale);
444class AsanFunctionInserter {
446 AsanFunctionInserter(
Module &M) :
M(
M) {}
448 template <
typename... ArgTypes>
449 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
450 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
463class RuntimeCallInserter {
465 bool TrackInsertedCalls =
false;
469 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
471 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
472 if (isScopedEHPersonality(Personality))
473 TrackInsertedCalls = true;
477 ~RuntimeCallInserter() {
478 if (InsertedCalls.
empty())
480 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
482 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
483 for (CallInst *CI : InsertedCalls) {
485 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
487 "Instruction doesn't belong to the expected Function!");
495 if (Colors.
size() != 1) {
497 "Instruction's BasicBlock is not monochromatic");
504 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
508 OB, CI->getIterator());
509 NewCall->copyMetadata(*CI);
510 CI->replaceAllUsesWith(NewCall);
511 CI->eraseFromParent();
516 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
518 const Twine &
Name =
"") {
521 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
522 if (TrackInsertedCalls)
523 InsertedCalls.push_back(Inst);
529struct AddressSanitizer {
530 AddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
531 const StackSafetyGlobalInfo *SSGI,
532 int InstrumentationWithCallsThreshold,
533 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
534 bool Recover =
false,
bool UseAfterScope =
false,
536 AsanDetectStackUseAfterReturnMode::Runtime)
537 : Opts(Opts),
M(
M), Inserter(
M),
538 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
539 Recover(
valueOr(Opts.asan_recover, Recover)),
540 UseAfterScope(UseAfterScope || Opts.asan_use_after_scope),
541 UseAfterReturn(Opts.asan_use_after_return.value_or(UseAfterReturn)),
542 SSGI(SSGI), InstrumentationWithCallsThreshold(
543 Opts.asan_instrumentation_with_call_threshold.value_or(
544 InstrumentationWithCallsThreshold)),
545 MaxInlinePoisoningSize(Opts.asan_max_inline_poisoning_size.value_or(
546 MaxInlinePoisoningSize)) {
547 C = &(
M.getContext());
548 DL = &
M.getDataLayout();
549 LongSize =
M.getDataLayout().getPointerSizeInBits();
550 IntptrTy = Type::getIntNTy(*
C, LongSize);
551 PtrTy = PointerType::getUnqual(*
C);
552 Int32Ty = Type::getInt32Ty(*
C);
553 TargetTriple =
M.getTargetTriple();
558 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
566 bool isInterestingAlloca(
const AllocaInst &AI);
568 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
570 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
571 const TargetTransformInfo *
TTI);
573 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
574 InterestingMemoryOperand &O,
bool UseCalls,
575 const DataLayout &
DL, RuntimeCallInserter &RTCI);
576 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
577 RuntimeCallInserter &RTCI);
579 Value *Addr, MaybeAlign Alignment,
580 uint32_t TypeStoreSize,
bool IsWrite,
581 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
582 RuntimeCallInserter &RTCI);
583 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
584 Instruction *InsertBefore,
Value *Addr,
585 uint32_t TypeStoreSize,
bool IsWrite,
586 Value *SizeArgument);
589 void instrumentUnusualSizeOrAlignment(Instruction *
I,
590 Instruction *InsertBefore,
Value *Addr,
591 TypeSize TypeStoreSize,
bool IsWrite,
592 Value *SizeArgument,
bool UseCalls,
594 RuntimeCallInserter &RTCI);
595 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
598 MaybeAlign Alignment,
unsigned Granularity,
599 Type *OpType,
bool IsWrite,
600 Value *SizeArgument,
bool UseCalls,
601 uint32_t Exp, RuntimeCallInserter &RTCI);
603 Value *ShadowValue, uint32_t TypeStoreSize);
605 bool IsWrite,
size_t AccessSizeIndex,
606 Value *SizeArgument, uint32_t Exp,
607 RuntimeCallInserter &RTCI);
608 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
610 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
611 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
612 const TargetTransformInfo *
TTI);
613 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
614 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
615 void markEscapedLocalAllocas(
Function &
F);
616 void markCatchParametersAsUninteresting(
Function &
F);
619 friend struct FunctionStackPoisoner;
621 void initializeCallbacks(
const TargetLibraryInfo *TLI);
623 bool LooksLikeCodeInBug11395(Instruction *
I);
624 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
625 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
626 TypeSize TypeStoreSize)
const;
629 struct FunctionStateRAII {
630 AddressSanitizer *
Pass;
632 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
634 "last pass forgot to clear cache");
638 ~FunctionStateRAII() {
639 Pass->LocalDynamicShadow =
nullptr;
640 Pass->ProcessedAllocas.clear();
644 const InstrumentationOptions &Opts;
646 AsanFunctionInserter Inserter;
648 const DataLayout *
DL;
658 ShadowMapping Mapping;
659 FunctionCallee AsanHandleNoReturnFunc;
660 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
668 FunctionCallee AsanErrorCallbackSized[2][2];
669 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
670 FunctionCallee AsanAssumeDereferenceableCallback;
672 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
673 Value *LocalDynamicShadow =
nullptr;
674 const StackSafetyGlobalInfo *SSGI;
675 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
677 FunctionCallee AMDGPUAddressShared;
678 FunctionCallee AMDGPUAddressPrivate;
679 int InstrumentationWithCallsThreshold;
680 uint32_t MaxInlinePoisoningSize;
683class ModuleAddressSanitizer {
685 ModuleAddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
686 bool InsertVersionCheck,
bool CompileKernel =
false,
687 bool Recover =
false,
bool UseGlobalsGC =
true,
688 bool UseOdrIndicator =
true,
691 : Opts(Opts),
M(
M), Inserter(
M),
692 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
693 InsertVersionCheck(
valueOr(Opts.asan_guard_against_version_mismatch,
694 InsertVersionCheck)),
695 Recover(
valueOr(Opts.asan_recover, Recover)),
696 UseGlobalsGC(UseGlobalsGC && Opts.asan_globals_live_support &&
697 !this->CompileKernel),
699 UsePrivateAlias(
valueOr(Opts.asan_use_private_alias, UseOdrIndicator)),
700 UseOdrIndicator(
valueOr(Opts.asan_use_odr_indicator, UseOdrIndicator)),
709 UseCtorComdat(UseGlobalsGC && Opts.asan_with_comdat &&
710 !this->CompileKernel),
711 DestructorKind(Opts.asan_destructor_kind.value_or(DestructorKind)),
712 ConstructorKind(Opts.asan_constructor_kind.value_or(ConstructorKind)) {
713 C = &(
M.getContext());
714 int LongSize =
M.getDataLayout().getPointerSizeInBits();
715 IntptrTy = Type::getIntNTy(*
C, LongSize);
716 PtrTy = PointerType::getUnqual(*
C);
717 TargetTriple =
M.getTargetTriple();
721 assert(this->DestructorKind != AsanDtorKind::Invalid);
724 bool instrumentModule();
727 void initializeCallbacks();
729 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
736 const std::string &UniqueModuleId);
741 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
745 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
746 StringRef OriginalName);
747 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
748 StringRef InternalSuffix);
751 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
752 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
753 bool ShouldUseMachOGlobalsSection()
const;
754 StringRef getGlobalMetadataSection()
const;
755 void poisonOneInitializer(
Function &GlobalInit);
756 void createInitializerPoisonCalls();
757 uint64_t getMinRedzoneSizeForGlobal()
const {
761 int GetAsanVersion()
const;
762 GlobalVariable *getOrCreateModuleName();
764 const InstrumentationOptions &Opts;
766 AsanFunctionInserter Inserter;
768 bool InsertVersionCheck;
771 bool UsePrivateAlias;
772 bool UseOdrIndicator;
780 ShadowMapping Mapping;
781 FunctionCallee AsanPoisonGlobals;
782 FunctionCallee AsanUnpoisonGlobals;
783 FunctionCallee AsanRegisterGlobals;
784 FunctionCallee AsanUnregisterGlobals;
785 FunctionCallee AsanRegisterImageGlobals;
786 FunctionCallee AsanUnregisterImageGlobals;
787 FunctionCallee AsanRegisterElfGlobals;
788 FunctionCallee AsanUnregisterElfGlobals;
790 Function *AsanCtorFunction =
nullptr;
791 Function *AsanDtorFunction =
nullptr;
792 GlobalVariable *ModuleName =
nullptr;
804struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
805 const InstrumentationOptions &Opts;
807 AddressSanitizer &ASan;
808 RuntimeCallInserter &RTCI;
813 ShadowMapping Mapping;
817 SmallVector<Instruction *, 8> RetVec;
821 FunctionCallee AsanSetShadowFunc[0x100] = {};
822 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
823 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
826 struct AllocaPoisonCall {
827 IntrinsicInst *InsBefore;
837 AllocaInst *DynamicAllocaLayout =
nullptr;
838 IntrinsicInst *LocalEscapeCall =
nullptr;
840 bool HasInlineAsm =
false;
841 bool HasReturnsTwiceCall =
false;
844 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
845 RuntimeCallInserter &RTCI)
846 : Opts(ASan.Opts),
F(
F), ASan(ASan), RTCI(RTCI),
848 IntptrTy(ASan.IntptrTy),
850 Mapping(ASan.Mapping),
851 PoisonStack(Opts.asan_stack &&
852 !
F.
getParent()->getTargetTriple().isAMDGPU()) {}
858 if (Opts.asan_redzone_byval_args)
859 copyArgsPassedByValToAllocas();
864 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
866 initializeCallbacks(*
F.getParent());
868 processDynamicAllocas();
869 processStaticAllocas();
871 if (Opts.asan_debug_stack) {
880 void copyArgsPassedByValToAllocas();
885 void processStaticAllocas();
886 void processDynamicAllocas();
888 void createDynamicAllocasInitStorage();
893 void visitReturnInst(ReturnInst &RI) {
894 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
901 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
904 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
906 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
916 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
922 RTCI.createRuntimeCall(
923 IRB, AsanAllocasUnpoisonFunc,
924 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
928 void unpoisonDynamicAllocas() {
929 for (Instruction *Ret : RetVec)
930 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
932 for (Instruction *StackRestoreInst : StackRestoreVec)
933 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
934 StackRestoreInst->getOperand(0));
947 void handleDynamicAllocaCall(AllocaInst *AI);
950 void visitAllocaInst(AllocaInst &AI) {
952 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
956 if (AllocaVec.
empty())
972 void visitIntrinsicInst(IntrinsicInst &
II) {
974 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
975 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
976 if (!ASan.UseAfterScope)
978 if (!
II.isLifetimeStartOrEnd())
983 if (!AI || !ASan.isInterestingAlloca(*AI))
993 bool DoPoison = (
ID == Intrinsic::lifetime_end);
994 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
996 StaticAllocaPoisonCallVec.
push_back(APC);
997 else if (Opts.asan_instrument_dynamic_allocas)
998 DynamicAllocaPoisonCallVec.
push_back(APC);
1001 void visitCallBase(CallBase &CB) {
1003 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1004 HasReturnsTwiceCall |= CI->canReturnTwice();
1009 void initializeCallbacks(
Module &M);
1014 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1016 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1019 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1020 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1025 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1028 Instruction *ThenTerm,
Value *ValueIfFalse);
1035 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1036 OS, MapClassName2PassName);
1038 if (Options.CompileKernel)
1040 if (Options.UseAfterScope)
1041 OS <<
"use-after-scope";
1049 : Options(Options), UseGlobalGC(UseGlobalGC),
1050 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1051 ConstructorKind(ConstructorKind) {}
1060 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
1061 ModuleAddressSanitizer ModuleSanitizer(Opts, M, Options.InsertVersionCheck,
1062 Options.CompileKernel, Options.Recover,
1063 UseGlobalGC, UseOdrIndicator,
1064 DestructorKind, ConstructorKind);
1075 if (!Opts.asan_debug_func.empty() && Opts.asan_debug_func ==
F.getName())
1077 if (
F.getName().starts_with(
"__asan_"))
1079 if (
F.isPresplitCoroutine())
1081 AddressSanitizer FunctionSanitizer(
1082 Opts, M, SSGI, Options.InstrumentationWithCallsThreshold,
1083 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1084 Options.UseAfterScope, Options.UseAfterReturn);
1087 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1089 Modified |= ModuleSanitizer.instrumentModule();
1110 if (
G->getName().starts_with(
"llvm.") ||
1112 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1114 G->getName().starts_with(
"__llvm_rtti_proxy"))
1130 if (AddrSpace == 3 || AddrSpace == 5)
1140 if (!Opts.asan_instrument_address_spaces.empty())
1141 return is_contained(Opts.asan_instrument_address_spaces, AddrSpace);
1146 return AddrSpace == 0;
1150 if (TargetTriple.isOSDarwin() &&
1154 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1157 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1158 if (Mapping.Offset == 0)
return Shadow;
1161 if (LocalDynamicShadow)
1162 ShadowBase = LocalDynamicShadow;
1164 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1165 if (Mapping.OrShadowOffset)
1166 return IRB.
CreateOr(Shadow, ShadowBase);
1168 return IRB.
CreateAdd(Shadow, ShadowBase);
1173 RuntimeCallInserter &RTCI) {
1176 RTCI.createRuntimeCall(
1182 RTCI.createRuntimeCall(
1188 MI->eraseFromParent();
1192bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1193 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1196 return It->getSecond();
1198 bool IsInteresting =
1209 !(SSGI && SSGI->
isSafe(AI)));
1211 It->second = IsInteresting;
1212 return IsInteresting;
1232 if (Opts.asan_skip_promotable_allocas && !isInterestingAlloca(*AI))
1242void AddressSanitizer::getInterestingMemoryOperands(
1246 if (LocalDynamicShadow ==
I)
1250 if (!Opts.asan_instrument_reads || ignoreAccess(
I, LI->getPointerOperand()))
1252 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1253 LI->getType(), LI->getAlign());
1255 if (!Opts.asan_instrument_writes ||
1256 ignoreAccess(
I,
SI->getPointerOperand()))
1259 SI->getValueOperand()->getType(),
SI->getAlign());
1261 if (!Opts.asan_instrument_atomics ||
1262 ignoreAccess(
I, RMW->getPointerOperand()))
1264 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1265 RMW->getValOperand()->getType(), std::nullopt);
1267 if (!Opts.asan_instrument_atomics ||
1268 ignoreAccess(
I, XCHG->getPointerOperand()))
1270 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1271 XCHG->getCompareOperand()->getType(),
1274 switch (CI->getIntrinsicID()) {
1275 case Intrinsic::masked_load:
1276 case Intrinsic::masked_store:
1277 case Intrinsic::masked_gather:
1278 case Intrinsic::masked_scatter: {
1279 bool IsWrite = CI->getType()->isVoidTy();
1281 unsigned OpOffset = IsWrite ? 1 : 0;
1282 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1285 auto BasePtr = CI->getOperand(OpOffset);
1286 if (ignoreAccess(
I, BasePtr))
1288 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1290 Value *
Mask = CI->getOperand(1 + OpOffset);
1291 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1294 case Intrinsic::masked_expandload:
1295 case Intrinsic::masked_compressstore: {
1296 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1297 unsigned OpOffset = IsWrite ? 1 : 0;
1298 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1300 auto BasePtr = CI->getOperand(OpOffset);
1301 if (ignoreAccess(
I, BasePtr))
1304 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1307 Value *
Mask = CI->getOperand(1 + OpOffset);
1310 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1311 Value *EVL =
IB.CreateAddReduce(ExtMask);
1312 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1313 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1317 case Intrinsic::vp_load:
1318 case Intrinsic::vp_store:
1319 case Intrinsic::experimental_vp_strided_load:
1320 case Intrinsic::experimental_vp_strided_store: {
1322 unsigned IID = CI->getIntrinsicID();
1323 bool IsWrite = CI->getType()->isVoidTy();
1324 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1326 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1327 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1329 Value *Stride =
nullptr;
1330 if (IID == Intrinsic::experimental_vp_strided_store ||
1331 IID == Intrinsic::experimental_vp_strided_load) {
1332 Stride = VPI->getOperand(PtrOpNo + 1);
1336 unsigned PointerAlign =
Alignment.valueOrOne().value();
1341 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1342 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1346 case Intrinsic::vp_gather:
1347 case Intrinsic::vp_scatter: {
1349 unsigned IID = CI->getIntrinsicID();
1350 bool IsWrite = IID == Intrinsic::vp_scatter;
1351 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1353 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1354 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1356 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1357 VPI->getMaskParam(),
1358 VPI->getVectorLengthParam());
1364 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1368 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1369 if (!Opts.asan_instrument_byval || !CI->isByValArgument(ArgNo) ||
1370 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1372 Type *Ty = CI->getParamByValType(ArgNo);
1388 if (!Cmp->isRelational())
1402 if (BO->getOpcode() != Instruction::Sub)
1415 if (!
G->hasInitializer())
1418 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1425 Type *Ty = V->getType();
1426 if (Ty->isPtrOrPtrVectorTy())
1432bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1434 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1449 "invalid vector pointer pair instrumentation operands");
1450 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1451 Index != NumElements; ++Index) {
1452 Value *ScalarParam[2] = {
1459 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1466 RTCI.createRuntimeCall(IRB,
F, Param);
1473 TypeSize TypeStoreSize,
bool IsWrite,
1474 Value *SizeArgument,
bool UseCalls,
1475 uint32_t Exp, RuntimeCallInserter &RTCI) {
1480 switch (FixedSize) {
1486 if (!Alignment || *Alignment >= Granularity ||
1487 *Alignment >= FixedSize / 8)
1488 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1489 FixedSize, IsWrite,
nullptr, UseCalls,
1493 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1494 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1497void AddressSanitizer::instrumentMaskedLoadOrStore(
1500 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1501 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1502 RuntimeCallInserter &RTCI) {
1504 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1505 auto Zero = ConstantInt::get(IntptrTy, 0);
1513 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1515 IB.SetInsertPoint(LoopInsertBefore);
1517 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1520 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1521 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1523 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1528 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1532 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1533 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1534 if (MaskElemC->isZero())
1540 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1541 MaskElem, &*IRB.GetInsertPoint(), false);
1542 IRB.SetInsertPoint(ThenTerm);
1545 Value *InstrumentedAddress;
1548 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1549 "Expected vector of pointer.");
1550 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1551 }
else if (Stride) {
1558 Alignment, Granularity, ElemTypeSize, IsWrite,
1559 SizeArgument, UseCalls, Exp, RTCI);
1566 RuntimeCallInserter &RTCI) {
1567 Value *Addr =
O.getPtr();
1580 uint32_t
Exp = Opts.asan_force_experiment;
1582 if (Opts.asan_opt && Opts.asan_opt_globals) {
1587 (!Opts.asan_initialization_order || GlobalIsLinkerInitialized(
G)) &&
1588 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1589 NumOptimizedAccessesToGlobalVar++;
1594 if (Opts.asan_opt && Opts.asan_opt_stack) {
1597 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1598 NumOptimizedAccessesToStackVar++;
1604 NumInstrumentedWrites++;
1606 NumInstrumentedReads++;
1608 if (
O.MaybeByteOffset) {
1613 if (TargetTriple.isRISCV()) {
1618 static_cast<unsigned>(LongSize)) {
1627 unsigned Granularity = 1 << Mapping.Scale;
1629 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1630 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1631 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1632 UseCalls, Exp, RTCI);
1635 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1636 UseCalls, Exp, RTCI);
1641 Value *Addr,
bool IsWrite,
1642 size_t AccessSizeIndex,
1643 Value *SizeArgument,
1645 RuntimeCallInserter &RTCI) {
1651 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1652 {Addr, SizeArgument});
1654 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1655 {Addr, SizeArgument, ExpVal});
1658 Call = RTCI.createRuntimeCall(
1659 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1661 Call = RTCI.createRuntimeCall(
1662 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1671 uint32_t TypeStoreSize) {
1672 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1674 Value *LastAccessedByte =
1675 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1677 if (TypeStoreSize / 8 > 1)
1679 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1682 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1687Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1689 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1696 return InsertBefore;
1701 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1703 Value *AddrSpaceZeroLanding =
1706 return InsertBefore;
1721 Trm->getParent()->setName(
"asan.report");
1732void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1735 uint32_t TypeStoreSize,
bool IsWrite,
1736 Value *SizeArgument,
bool UseCalls,
1738 RuntimeCallInserter &RTCI) {
1739 if (TargetTriple.isAMDGPU()) {
1740 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1741 TypeStoreSize, IsWrite, SizeArgument);
1749 if (UseCalls && Opts.asan_optimize_callbacks) {
1750 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1753 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
1760 RTCI.createRuntimeCall(
1761 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1763 RTCI.createRuntimeCall(
1764 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1765 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
1772 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1774 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
1779 size_t Granularity = 1ULL << Mapping.Scale;
1783 (Opts.asan_always_slow_path || (TypeStoreSize < 8 * Granularity));
1785 if (TargetTriple.isAMDGCN()) {
1787 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1790 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
1791 }
else if (GenSlowPath) {
1798 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1813 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
1822void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1824 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
1825 uint32_t Exp, RuntimeCallInserter &RTCI) {
1833 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
1836 RTCI.createRuntimeCall(
1837 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
1851void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
1856 Value *ModuleNameAddr =
1864 for (
auto &BB : GlobalInit)
1876void ModuleAddressSanitizer::createInitializerPoisonCalls() {
1896 poisonOneInitializer(*
F);
1902ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
1907 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
1919bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
1920 Type *Ty =
G->getValueType();
1923 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
1925 if (!Ty->
isSized())
return false;
1926 if (!
G->hasInitializer())
return false;
1933 if (
G->isThreadLocal())
return false;
1935 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
1941 if (!TargetTriple.isOSBinFormatCOFF()) {
1942 if (!
G->hasExactDefinition() ||
G->hasComdat())
1946 if (
G->isInterposable())
1950 if (
G->hasAvailableExternallyLinkage())
1957 switch (
C->getSelectionKind()) {
1968 if (
G->hasSection()) {
1978 if (Section ==
"llvm.metadata")
return false;
1985 if (
Section.starts_with(
".preinit_array") ||
1986 Section.starts_with(
".init_array") ||
1987 Section.starts_with(
".fini_array")) {
1993 if (TargetTriple.isOSBinFormatELF()) {
2007 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2008 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2013 if (TargetTriple.isOSBinFormatMachO()) {
2015 unsigned TAA = 0, StubSize = 0;
2018 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2023 if (ParsedSegment ==
"__OBJC" ||
2024 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2036 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2049 if (CompileKernel) {
2052 if (
G->getName().starts_with(
"__"))
2062bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2063 if (!TargetTriple.isOSBinFormatMachO())
2066 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2068 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2070 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2072 if (TargetTriple.isDriverKit())
2074 if (TargetTriple.isXROS())
2080StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2081 switch (TargetTriple.getObjectFormat()) {
2091 "ModuleAddressSanitizer not implemented for object file format");
2098void ModuleAddressSanitizer::initializeCallbacks() {
2104 AsanUnpoisonGlobals =
2108 AsanRegisterGlobals = Inserter.insertFunction(
2110 AsanUnregisterGlobals = Inserter.insertFunction(
2115 AsanRegisterImageGlobals = Inserter.insertFunction(
2117 AsanUnregisterImageGlobals = Inserter.insertFunction(
2120 AsanRegisterElfGlobals =
2122 IntptrTy, IntptrTy, IntptrTy);
2123 AsanUnregisterElfGlobals =
2125 IntptrTy, IntptrTy, IntptrTy);
2130void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2135 if (!
G->hasName()) {
2139 G->setName(
genName(
"anon_global"));
2142 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2143 std::string
Name = std::string(
G->getName());
2144 Name += InternalSuffix;
2145 C =
M.getOrInsertComdat(Name);
2147 C =
M.getOrInsertComdat(
G->getName());
2153 if (TargetTriple.isOSBinFormatCOFF()) {
2155 if (
G->hasPrivateLinkage())
2168ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2170 auto Linkage = TargetTriple.isOSBinFormatMachO()
2176 Metadata->setSection(getGlobalMetadataSection());
2183Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2187 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2195void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2199 auto &
DL =
M.getDataLayout();
2202 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2203 Constant *Initializer = MetadataInitializers[i];
2207 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2213 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2215 "global metadata will not be padded appropriately");
2218 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2223 if (!MetadataGlobals.empty())
2227void ModuleAddressSanitizer::instrumentGlobalsELF(
2230 const std::string &UniqueModuleId) {
2237 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2240 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2243 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2245 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2248 if (UseComdatForGlobalsGC)
2249 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2254 if (!MetadataGlobals.empty())
2271 "__start_" + getGlobalMetadataSection());
2275 "__stop_" + getGlobalMetadataSection());
2289 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2296void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2307 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2308 Constant *Initializer = MetadataInitializers[i];
2314 auto LivenessBinder =
2319 Twine(
"__asan_binder_") +
G->getName());
2320 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2321 LivenessGlobals[i] = Liveness;
2328 if (!LivenessGlobals.empty())
2350 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2355void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2359 unsigned N = ExtendedGlobals.
size();
2369 if (Mapping.Scale > 3)
2375 ConstantInt::get(IntptrTy,
N)});
2381 IrbDtor.CreateCall(AsanUnregisterGlobals,
2383 ConstantInt::get(IntptrTy,
N)});
2392void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2397 if (CompileKernel) {
2398 for (
auto &GA :
M.aliases()) {
2400 AliasedGlobalExclusions.
insert(GV);
2405 for (
auto &
G :
M.globals()) {
2406 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2410 size_t n = GlobalsToChange.
size();
2411 auto &
DL =
M.getDataLayout();
2425 IntptrTy, IntptrTy, IntptrTy);
2429 for (
size_t i = 0; i < n; i++) {
2433 if (
G->hasSanitizerMetadata())
2434 MD =
G->getSanitizerMetadata();
2439 std::string NameForGlobal =
G->getName().str();
2444 Type *Ty =
G->getValueType();
2445 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2458 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2459 G->getThreadLocalMode(),
G->getAddressSpace());
2469 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2472 if (Seq && Seq->isCString())
2473 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2480 G->replaceAllUsesWith(NewGlobal);
2482 G->eraseFromParent();
2483 NewGlobals[i] = NewGlobal;
2488 bool CanUsePrivateAliases =
2489 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2490 TargetTriple.isOSBinFormatWasm();
2491 if (CanUsePrivateAliases && UsePrivateAlias) {
2494 InstrumentedGlobal =
2501 }
else if (UseOdrIndicator) {
2504 auto *ODRIndicatorSym =
2513 ODRIndicatorSym->setAlignment(
Align(1));
2520 ConstantInt::get(IntptrTy, SizeInBytes),
2521 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2524 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2529 Initializers[i] = Initializer;
2535 for (
size_t i = 0; i < n; i++) {
2537 if (
G->getName().empty())
continue;
2542 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2549 }
else if (n == 0) {
2552 *CtorComdat = TargetTriple.isOSBinFormatELF();
2554 *CtorComdat =
false;
2555 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2556 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2557 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2558 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2560 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2565 if (Opts.asan_initialization_order)
2566 createInitializerPoisonCalls();
2572ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2573 constexpr uint64_t kMaxRZ = 1 << 18;
2574 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2577 if (SizeInBytes <= MinRZ / 2) {
2581 RZ = MinRZ - SizeInBytes;
2584 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2587 if (SizeInBytes % MinRZ)
2588 RZ += MinRZ - (SizeInBytes % MinRZ);
2591 assert((RZ + SizeInBytes) % MinRZ == 0);
2596int ModuleAddressSanitizer::GetAsanVersion()
const {
2597 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2598 bool isAndroid =
M.getTargetTriple().isAndroid();
2602 Version += (LongSize == 32 && isAndroid);
2617bool ModuleAddressSanitizer::instrumentModule() {
2618 initializeCallbacks();
2626 if (CompileKernel) {
2631 std::string AsanVersion = std::to_string(GetAsanVersion());
2632 std::string VersionCheckName =
2634 std::tie(AsanCtorFunction, std::ignore) =
2637 {}, VersionCheckName);
2641 bool CtorComdat =
true;
2642 if (Opts.asan_globals) {
2644 if (AsanCtorFunction) {
2645 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2646 instrumentGlobals(IRB, &CtorComdat);
2649 instrumentGlobals(IRB, &CtorComdat);
2658 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2659 if (AsanCtorFunction) {
2663 if (AsanDtorFunction) {
2668 if (AsanCtorFunction)
2670 if (AsanDtorFunction)
2680 const std::string EndingStr = Recover ?
"_noabort" :
"";
2681 AsanAssumeDereferenceableCallback =
M.getOrInsertFunction(
2682 "__asan_report_assume_dereferenceable" + EndingStr,
2687 for (
int Exp = 0;
Exp < 2;
Exp++) {
2688 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2689 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2690 const std::string ExpStr =
Exp ?
"exp_" :
"";
2691 const std::string EndingStr = Recover ?
"_noabort" :
"";
2701 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2702 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2703 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2706 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2710 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2711 Inserter.insertFunction(
2712 (Opts.asan_memory_access_callback_prefix + ExpStr + TypeStr +
2718 AccessSizeIndex++) {
2719 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2720 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2721 Inserter.insertFunction(
2725 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2726 Inserter.insertFunction(
2727 (Opts.asan_memory_access_callback_prefix + ExpStr + Suffix +
2735 const std::string MemIntrinCallbackPrefix =
2736 (CompileKernel && !Opts.asan_kernel_mem_intrinsic_prefix)
2738 : Opts.asan_memory_access_callback_prefix.str();
2739 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2740 PtrTy, PtrTy, PtrTy, IntptrTy);
2741 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2742 PtrTy, PtrTy, PtrTy, IntptrTy);
2744 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
2749 AsanHandleNoReturnFunc =
2752 AsanPtrCmpFunction =
2754 AsanPtrSubFunction =
2756 if (Mapping.InGlobal)
2757 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
2760 AMDGPUAddressShared =
2766bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2774 if (
F.getName().contains(
" load]")) {
2784bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
2790 if (Mapping.InGlobal) {
2791 if (Opts.asan_with_ifunc_suppress_remat) {
2798 LocalDynamicShadow =
2799 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
2801 LocalDynamicShadow =
2805 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
2807 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
2812void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
2817 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
2821 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
2827 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
2829 for (
Value *Arg :
II->args()) {
2832 "non-static alloca arg to localescape");
2833 ProcessedAllocas[AI] =
false;
2842void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
2848 for (
Value *Operand : CatchPad->arg_operands())
2850 ProcessedAllocas[AI] =
false;
2856bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
2857 bool ShouldInstrument = Opts.asan_debug_min < 0 || Opts.asan_debug_max < 0 ||
2858 (Instrumented >= Opts.asan_debug_min &&
2859 Instrumented <= Opts.asan_debug_max);
2861 return !ShouldInstrument;
2864bool AddressSanitizer::instrumentFunction(
Function &
F,
2867 bool FunctionModified =
false;
2870 if (
F.hasFnAttribute(Attribute::Naked))
2871 return FunctionModified;
2876 if (maybeInsertAsanInitAtFunctionEntry(
F))
2877 FunctionModified =
true;
2880 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
2882 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2883 return FunctionModified;
2887 initializeCallbacks(TLI);
2889 FunctionStateRAII CleanupObj(
this);
2891 RuntimeCallInserter RTCI(
F);
2893 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
2897 markEscapedLocalAllocas(
F);
2899 if (TargetTriple.isOSWindows())
2900 markCatchParametersAsUninteresting(
F);
2913 for (
auto &BB :
F) {
2915 TempsToInstrument.
clear();
2916 int NumInsnsPerBB = 0;
2917 for (
auto &Inst : BB) {
2918 if (LooksLikeCodeInBug11395(&Inst))
return false;
2926 if (!InterestingOperands.
empty()) {
2927 for (
auto &Operand : InterestingOperands) {
2928 if (Opts.asan_opt && Opts.asan_opt_same_temp) {
2929 Value *Ptr = Operand.getPtr();
2933 if (Operand.MaybeMask) {
2934 if (TempsToInstrument.
count(Ptr))
2937 if (!TempsToInstrument.
insert(Ptr).second)
2941 OperandsToInstrument.
push_back(Operand);
2944 }
else if (((Opts.asan_detect_invalid_pointer_pair ||
2945 Opts.asan_detect_invalid_pointer_cmp) &&
2947 ((Opts.asan_detect_invalid_pointer_pair ||
2948 Opts.asan_detect_invalid_pointer_sub) &&
2950 PointerComparisonsOrSubtracts.
push_back(&Inst);
2955 }
else if (Opts.asan_instrument_assume_dereferenceable &&
2964 TempsToInstrument.
clear();
2971 if (NumInsnsPerBB >= Opts.asan_max_ins_per_bb)
2976 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
2977 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
2978 (
unsigned)InstrumentationWithCallsThreshold);
2983 int NumInstrumented = 0;
2984 for (
auto &Operand : OperandsToInstrument) {
2985 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2986 instrumentMop(ObjSizeVis, Operand, UseCalls,
2987 F.getDataLayout(), RTCI);
2988 FunctionModified =
true;
2990 for (
auto *Inst : IntrinToInstrument) {
2991 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2992 instrumentMemIntrinsic(Inst, RTCI);
2993 FunctionModified =
true;
2996 FunctionStackPoisoner FSP(
F, *
this, RTCI);
2997 bool ChangedStack = FSP.runOnFunction();
3001 for (
auto *CI : NoReturnCalls) {
3003 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3006 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3007 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3010 for (
auto *AI : DerefAssumptions) {
3012 Value *Ptr = Bundle->Inputs[0];
3025 RTCI.createRuntimeCall(IRB, AsanAssumeDereferenceableCallback,
3026 {AddrLong, SizeExt});
3028 FunctionModified =
true;
3032 if (ChangedStack || !NoReturnCalls.empty())
3033 FunctionModified =
true;
3035 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3038 return FunctionModified;
3044bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3045 if (LongSize != 32)
return false;
3054void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
3058 const char *MallocNameTemplate =
3063 std::string Suffix =
itostr(Index);
3064 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3065 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3066 AsanStackFreeFunc[
Index] =
3071 if (ASan.UseAfterScope) {
3072 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3074 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3078 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3079 0xf3, 0xf5, 0xf8}) {
3080 std::ostringstream
Name;
3082 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3083 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3087 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3089 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3095 size_t Begin,
size_t End,
3097 Value *ShadowBase) {
3101 const size_t LargestStoreSizeInBytes =
3102 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3104 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3110 for (
size_t i = Begin; i <
End;) {
3111 if (!ShadowMask[i]) {
3117 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3119 while (StoreSizeInBytes >
End - i)
3120 StoreSizeInBytes /= 2;
3123 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3124 while (j <= StoreSizeInBytes / 2)
3125 StoreSizeInBytes /= 2;
3129 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3131 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3133 Val = (Val << 8) | ShadowBytes[i + j];
3136 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3142 i += StoreSizeInBytes;
3149 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3154 size_t Begin,
size_t End,
3157 size_t Done = Begin;
3158 for (
size_t i = Begin, j = Begin + 1; i <
End; i =
j++) {
3159 if (!ShadowMask[i]) {
3163 uint8_t Val = ShadowBytes[i];
3164 if (!AsanSetShadowFunc[Val])
3168 for (;
j <
End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3171 if (j - i >= ASan.MaxInlinePoisoningSize) {
3172 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3173 RTCI.createRuntimeCall(
3174 IRB, AsanSetShadowFunc[Val],
3175 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3176 ConstantInt::get(IntptrTy, j - i)});
3181 copyToShadowInline(ShadowMask, ShadowBytes,
Done,
End, IRB, ShadowBase);
3189 for (
int i = 0;; i++, MaxSize *= 2)
3190 if (LocalStackSize <= MaxSize)
return i;
3194void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3196 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3204 if (Arg.hasByValAttr()) {
3205 Type *Ty = Arg.getParamByValType();
3207 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3211 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3214 Arg.replaceAllUsesWith(AI);
3216 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3217 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3225 Value *ValueIfFalse) {
3228 PHI->addIncoming(ValueIfFalse, CondBlock);
3230 PHI->addIncoming(ValueIfTrue, ThenBlock);
3234Value *FunctionStackPoisoner::createAllocaForLayout(
3243 nullptr,
"MyAlloca");
3246 assert((Opts.asan_realign_stack & (Opts.asan_realign_stack - 1)) == 0);
3248 std::max(
L.FrameAlignment,
uint64_t(Opts.asan_realign_stack));
3253void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3256 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3261void FunctionStackPoisoner::processDynamicAllocas() {
3262 if (!Opts.asan_instrument_dynamic_allocas || DynamicAllocaVec.
empty()) {
3268 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3271 assert(ASan.isInterestingAlloca(*APC.AI));
3272 assert(!APC.AI->isStaticAlloca());
3275 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3282 createDynamicAllocasInitStorage();
3283 for (
auto &AI : DynamicAllocaVec)
3284 handleDynamicAllocaCall(AI);
3285 unpoisonDynamicAllocas();
3297 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3314 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3319 bool IsArgInitViaCast =
3324 Val == It->getPrevNode();
3325 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3329 if (IsArgInitViaCast)
3344 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3347 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3351 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3354 auto MetadataString =
3356 if (MetadataString->getString() ==
"alloca_name_altered")
3365void FunctionStackPoisoner::processStaticAllocas() {
3366 if (AllocaVec.
empty()) {
3371 int StackMallocIdx = -1;
3373 if (
auto SP =
F.getSubprogram())
3374 EntryDebugLocation =
3383 auto InsBeforeB = InsBefore->
getParent();
3384 assert(InsBeforeB == &
F.getEntryBlock());
3385 for (
auto *AI : StaticAllocasToMoveUp)
3396 ArgInitInst->moveBefore(InsBefore->
getIterator());
3399 if (LocalEscapeCall)
3407 ASan.getAllocaSizeInBytes(*AI),
3418 uint64_t Granularity = 1ULL << Mapping.Scale;
3419 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3425 for (
auto &
Desc : SVD)
3429 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3432 assert(ASan.isInterestingAlloca(*APC.AI));
3433 assert(APC.AI->isStaticAlloca());
3438 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3439 if (LifetimeLoc->getFile() == FnLoc->getFile())
3440 if (
unsigned Line = LifetimeLoc->getLine())
3441 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3447 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3449 bool DoStackMalloc =
3452 bool DoDynamicAlloca = Opts.asan_stack_dynamic_alloca;
3459 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3460 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3462 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3463 Value *StaticAlloca =
3464 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3466 Value *FakeStackPtr;
3467 Value *FakeStackInt;
3468 Value *LocalStackBase;
3469 Value *LocalStackBaseAlloca;
3472 if (DoStackMalloc) {
3473 LocalStackBaseAlloca =
3474 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3481 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3491 Value *FakeStackValue =
3492 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3493 ConstantInt::get(IntptrTy, LocalStackSize));
3495 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3496 Term, ConstantInt::get(IntptrTy, 0));
3504 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3505 ConstantInt::get(IntptrTy, LocalStackSize));
3508 Value *NoFakeStack =
3513 Value *AllocaValue =
3514 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3518 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3519 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3527 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3528 LocalStackBaseAlloca = LocalStackBase;
3533 for (
const auto &
Desc : SVD) {
3537 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3550 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3558 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3565 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3568 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3570 if (!StaticAllocaPoisonCallVec.empty()) {
3574 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3577 size_t Begin =
Desc.Offset /
L.Granularity;
3578 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3581 copyToShadow(ShadowAfterScope,
3582 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin,
End,
3588 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3591 if (
I->isLifetimeStartOrEnd())
3592 I->eraseFromParent();
3605 if (DoStackMalloc) {
3606 assert(StackMallocIdx >= 0);
3623 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3625 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3627 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3629 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3631 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3632 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3633 IRBPoison.CreateStore(
3635 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3638 RTCI.createRuntimeCall(
3639 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3640 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3644 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3646 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3651 for (
auto *AI : AllocaVec)
3659 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3660 RTCI.createRuntimeCall(
3661 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3662 {AddrArg, SizeArg});
3673void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3681 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3715 ConstantInt::get(IntptrTy,
Alignment.value()));
3718 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3729 if (
I->isLifetimeStartOrEnd())
3730 I->eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void findStoresToUninstrumentedArgAllocas(AddressSanitizer &ASan, Instruction &InsBefore, SmallVectorImpl< Instruction * > &InitInsts)
Collect instructions in the entry block after InsBefore which initialize permanent storage for a func...
static 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 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
const char kAsanOptionDetectUseAfterReturn[]
static const uint64_t kRISCV64_ShadowOffset64
const char kAsanSetShadowPrefix[]
static Twine genName(StringRef suffix)
static uint64_t GetCtorAndDtorPriority(Triple &TargetTriple)
const char kAsanStackMallocNameTemplate[]
const char kAsanInitName[]
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
const char kAsanUnregisterGlobalsName[]
static const uint64_t kAsanCtorAndDtorPriority
const char kAsanUnpoisonGlobalsName[]
const char kAsanUnregisterElfGlobalsName[]
static bool isUnsupportedAMDGPUAddrspace(Value *Addr)
const char kAsanRegisterImageGlobalsName[]
static const uint64_t kWebAssemblyShadowOffset
static const uint64_t kAllocaRzSize
const char kODRGenPrefix[]
static const uint64_t kSystemZ_ShadowOffset64
static const uint64_t kDefaultShadowOffset32
const char kAsanShadowMemoryDynamicAddress[]
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
const char kAsanStackMallocAlwaysNameTemplate[]
static const uint64_t kAsanEmscriptenCtorAndDtorPriority
static const uint64_t kFreeBSD_ShadowOffset64
const char kSanCovGenPrefix[]
static const uint64_t kFreeBSDKasan_ShadowOffset64
const char kAsanModuleDtorName[]
static const uint64_t kDynamicShadowSentinel
static bool isInterestingPointerComparison(Instruction *I)
static const uint64_t kMIPS64_ShadowOffset64
static const uint64_t kLinuxKasan_ShadowOffset64
static int StackMallocSizeClass(uint64_t LocalStackSize)
constexpr size_t kAccessSizeIndexShift
const char kAsanPoisonStackMemoryName[]
static const size_t kNumberOfAccessSizes
const char kAsanUnpoisonStackMemoryName[]
static const uint64_t kLoongArch64_ShadowOffset64
const char kAsanRegisterGlobalsName[]
const char kAsanModuleCtorName[]
const char kAsanGlobalsRegisteredFlagName[]
static const size_t kMaxStackMallocSize
static ShadowMapping getShadowMapping(const InstrumentationOptions &Opts, const Triple &TargetTriple, int LongSize, bool IsKasan)
static const uint64_t kMIPS_ShadowOffsetN32
const char kAsanUnregisterImageGlobalsName[]
static const uintptr_t kCurrentStackFrameMagic
static const uint64_t kPPC64_ShadowOffset64
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kMIPS32_ShadowOffset32
static const uint64_t kNetBSD_ShadowOffset32
static const uint64_t kFreeBSDAArch64_ShadowOffset64
static const uint64_t kSmallX86_64ShadowOffsetBase
static const uint64_t kNetBSD_ShadowOffset64
static bool isSupportedAddrspace(const InstrumentationOptions &Opts, const Triple &TargetTriple, Value *Addr)
static const uint64_t kWindowsShadowOffset32
static size_t TypeStoreSizeToSizeIndex(uint32_t TypeSize)
const char kAsanAllocaPoison[]
constexpr size_t kCompileKernelShift
const char kAsanVersionCheckNamePrefix[]
const char kAMDGPUAddressPrivateName[]
static const uint64_t kNetBSDKasan_ShadowOffset64
const char kAMDGPUBallotName[]
const char kAsanRegisterElfGlobalsName[]
const char kAsanReportErrorTemplate[]
static StringRef getAllocaName(AllocaInst *AI)
static const uintptr_t kRetiredStackFrameMagic
const char kAsanPoisonGlobalsName[]
const char kAsanHandleNoReturnName[]
static const size_t kMinStackMallocSize
const char kAsanAllocasUnpoison[]
static const uint64_t kAArch64_ShadowOffset64
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")
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.
This represents the llvm.assume intrinsic.
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.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
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)
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
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.
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.
@ 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.
constexpr bool valueOr(BoolOrDefault X, bool Default)
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 ...
@ End
Run the machine verifier once, at the end of the pipeline.
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.
static constexpr Align fromLog2(unsigned Log2Value)
Returns an alignment of 1 << Log2Value bytes.
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.