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];
671 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
672 Value *LocalDynamicShadow =
nullptr;
673 const StackSafetyGlobalInfo *SSGI;
674 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
676 FunctionCallee AMDGPUAddressShared;
677 FunctionCallee AMDGPUAddressPrivate;
678 int InstrumentationWithCallsThreshold;
679 uint32_t MaxInlinePoisoningSize;
682class ModuleAddressSanitizer {
684 ModuleAddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
685 bool InsertVersionCheck,
bool CompileKernel =
false,
686 bool Recover =
false,
bool UseGlobalsGC =
true,
687 bool UseOdrIndicator =
true,
690 : Opts(Opts),
M(
M), Inserter(
M),
691 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
692 InsertVersionCheck(
valueOr(Opts.asan_guard_against_version_mismatch,
693 InsertVersionCheck)),
694 Recover(
valueOr(Opts.asan_recover, Recover)),
695 UseGlobalsGC(UseGlobalsGC && Opts.asan_globals_live_support &&
696 !this->CompileKernel),
698 UsePrivateAlias(
valueOr(Opts.asan_use_private_alias, UseOdrIndicator)),
699 UseOdrIndicator(
valueOr(Opts.asan_use_odr_indicator, UseOdrIndicator)),
708 UseCtorComdat(UseGlobalsGC && Opts.asan_with_comdat &&
709 !this->CompileKernel),
710 DestructorKind(Opts.asan_destructor_kind.value_or(DestructorKind)),
711 ConstructorKind(Opts.asan_constructor_kind.value_or(ConstructorKind)) {
712 C = &(
M.getContext());
713 int LongSize =
M.getDataLayout().getPointerSizeInBits();
714 IntptrTy = Type::getIntNTy(*
C, LongSize);
715 PtrTy = PointerType::getUnqual(*
C);
716 TargetTriple =
M.getTargetTriple();
720 assert(this->DestructorKind != AsanDtorKind::Invalid);
723 bool instrumentModule();
726 void initializeCallbacks();
728 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
735 const std::string &UniqueModuleId);
740 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
744 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
745 StringRef OriginalName);
746 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
747 StringRef InternalSuffix);
750 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
751 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
752 bool ShouldUseMachOGlobalsSection()
const;
753 StringRef getGlobalMetadataSection()
const;
754 void poisonOneInitializer(
Function &GlobalInit);
755 void createInitializerPoisonCalls();
756 uint64_t getMinRedzoneSizeForGlobal()
const {
760 int GetAsanVersion()
const;
761 GlobalVariable *getOrCreateModuleName();
763 const InstrumentationOptions &Opts;
765 AsanFunctionInserter Inserter;
767 bool InsertVersionCheck;
770 bool UsePrivateAlias;
771 bool UseOdrIndicator;
779 ShadowMapping Mapping;
780 FunctionCallee AsanPoisonGlobals;
781 FunctionCallee AsanUnpoisonGlobals;
782 FunctionCallee AsanRegisterGlobals;
783 FunctionCallee AsanUnregisterGlobals;
784 FunctionCallee AsanRegisterImageGlobals;
785 FunctionCallee AsanUnregisterImageGlobals;
786 FunctionCallee AsanRegisterElfGlobals;
787 FunctionCallee AsanUnregisterElfGlobals;
789 Function *AsanCtorFunction =
nullptr;
790 Function *AsanDtorFunction =
nullptr;
791 GlobalVariable *ModuleName =
nullptr;
803struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
804 const InstrumentationOptions &Opts;
806 AddressSanitizer &ASan;
807 RuntimeCallInserter &RTCI;
812 ShadowMapping Mapping;
816 SmallVector<Instruction *, 8> RetVec;
820 FunctionCallee AsanSetShadowFunc[0x100] = {};
821 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
822 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
825 struct AllocaPoisonCall {
826 IntrinsicInst *InsBefore;
836 AllocaInst *DynamicAllocaLayout =
nullptr;
837 IntrinsicInst *LocalEscapeCall =
nullptr;
839 bool HasInlineAsm =
false;
840 bool HasReturnsTwiceCall =
false;
843 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
844 RuntimeCallInserter &RTCI)
845 : Opts(ASan.Opts),
F(
F), ASan(ASan), RTCI(RTCI),
847 IntptrTy(ASan.IntptrTy),
849 Mapping(ASan.Mapping),
850 PoisonStack(Opts.asan_stack &&
851 !
F.
getParent()->getTargetTriple().isAMDGPU()) {}
857 if (Opts.asan_redzone_byval_args)
858 copyArgsPassedByValToAllocas();
863 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
865 initializeCallbacks(*
F.getParent());
867 processDynamicAllocas();
868 processStaticAllocas();
870 if (Opts.asan_debug_stack) {
879 void copyArgsPassedByValToAllocas();
884 void processStaticAllocas();
885 void processDynamicAllocas();
887 void createDynamicAllocasInitStorage();
892 void visitReturnInst(ReturnInst &RI) {
893 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
900 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
903 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
905 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
915 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
921 RTCI.createRuntimeCall(
922 IRB, AsanAllocasUnpoisonFunc,
923 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
927 void unpoisonDynamicAllocas() {
928 for (Instruction *Ret : RetVec)
929 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
931 for (Instruction *StackRestoreInst : StackRestoreVec)
932 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
933 StackRestoreInst->getOperand(0));
946 void handleDynamicAllocaCall(AllocaInst *AI);
949 void visitAllocaInst(AllocaInst &AI) {
951 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
955 if (AllocaVec.
empty())
971 void visitIntrinsicInst(IntrinsicInst &
II) {
973 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
974 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
975 if (!ASan.UseAfterScope)
977 if (!
II.isLifetimeStartOrEnd())
982 if (!AI || !ASan.isInterestingAlloca(*AI))
992 bool DoPoison = (
ID == Intrinsic::lifetime_end);
993 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
995 StaticAllocaPoisonCallVec.
push_back(APC);
996 else if (Opts.asan_instrument_dynamic_allocas)
997 DynamicAllocaPoisonCallVec.
push_back(APC);
1000 void visitCallBase(CallBase &CB) {
1002 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1003 HasReturnsTwiceCall |= CI->canReturnTwice();
1008 void initializeCallbacks(
Module &M);
1013 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1015 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1018 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1019 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1024 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1027 Instruction *ThenTerm,
Value *ValueIfFalse);
1034 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1035 OS, MapClassName2PassName);
1037 if (Options.CompileKernel)
1039 if (Options.UseAfterScope)
1040 OS <<
"use-after-scope";
1048 : Options(Options), UseGlobalGC(UseGlobalGC),
1049 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1050 ConstructorKind(ConstructorKind) {}
1059 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
1060 ModuleAddressSanitizer ModuleSanitizer(Opts, M, Options.InsertVersionCheck,
1061 Options.CompileKernel, Options.Recover,
1062 UseGlobalGC, UseOdrIndicator,
1063 DestructorKind, ConstructorKind);
1074 if (!Opts.asan_debug_func.empty() && Opts.asan_debug_func ==
F.getName())
1076 if (
F.getName().starts_with(
"__asan_"))
1078 if (
F.isPresplitCoroutine())
1080 AddressSanitizer FunctionSanitizer(
1081 Opts, M, SSGI, Options.InstrumentationWithCallsThreshold,
1082 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1083 Options.UseAfterScope, Options.UseAfterReturn);
1086 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1088 Modified |= ModuleSanitizer.instrumentModule();
1109 if (
G->getName().starts_with(
"llvm.") ||
1111 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1113 G->getName().starts_with(
"__llvm_rtti_proxy"))
1129 if (AddrSpace == 3 || AddrSpace == 5)
1139 if (!Opts.asan_instrument_address_spaces.empty())
1140 return is_contained(Opts.asan_instrument_address_spaces, AddrSpace);
1145 return AddrSpace == 0;
1149 if (TargetTriple.isOSDarwin() &&
1153 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1156 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1157 if (Mapping.Offset == 0)
return Shadow;
1160 if (LocalDynamicShadow)
1161 ShadowBase = LocalDynamicShadow;
1163 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1164 if (Mapping.OrShadowOffset)
1165 return IRB.
CreateOr(Shadow, ShadowBase);
1167 return IRB.
CreateAdd(Shadow, ShadowBase);
1172 RuntimeCallInserter &RTCI) {
1175 RTCI.createRuntimeCall(
1181 RTCI.createRuntimeCall(
1187 MI->eraseFromParent();
1191bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1192 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1195 return It->getSecond();
1197 bool IsInteresting =
1208 !(SSGI && SSGI->
isSafe(AI)));
1210 It->second = IsInteresting;
1211 return IsInteresting;
1231 if (Opts.asan_skip_promotable_allocas && !isInterestingAlloca(*AI))
1241void AddressSanitizer::getInterestingMemoryOperands(
1245 if (LocalDynamicShadow ==
I)
1249 if (!Opts.asan_instrument_reads || ignoreAccess(
I, LI->getPointerOperand()))
1251 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1252 LI->getType(), LI->getAlign());
1254 if (!Opts.asan_instrument_writes ||
1255 ignoreAccess(
I,
SI->getPointerOperand()))
1258 SI->getValueOperand()->getType(),
SI->getAlign());
1260 if (!Opts.asan_instrument_atomics ||
1261 ignoreAccess(
I, RMW->getPointerOperand()))
1263 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1264 RMW->getValOperand()->getType(), std::nullopt);
1266 if (!Opts.asan_instrument_atomics ||
1267 ignoreAccess(
I, XCHG->getPointerOperand()))
1269 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1270 XCHG->getCompareOperand()->getType(),
1273 switch (CI->getIntrinsicID()) {
1274 case Intrinsic::masked_load:
1275 case Intrinsic::masked_store:
1276 case Intrinsic::masked_gather:
1277 case Intrinsic::masked_scatter: {
1278 bool IsWrite = CI->getType()->isVoidTy();
1280 unsigned OpOffset = IsWrite ? 1 : 0;
1281 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1284 auto BasePtr = CI->getOperand(OpOffset);
1285 if (ignoreAccess(
I, BasePtr))
1287 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1289 Value *
Mask = CI->getOperand(1 + OpOffset);
1290 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1293 case Intrinsic::masked_expandload:
1294 case Intrinsic::masked_compressstore: {
1295 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1296 unsigned OpOffset = IsWrite ? 1 : 0;
1297 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1299 auto BasePtr = CI->getOperand(OpOffset);
1300 if (ignoreAccess(
I, BasePtr))
1303 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1306 Value *
Mask = CI->getOperand(1 + OpOffset);
1309 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1310 Value *EVL =
IB.CreateAddReduce(ExtMask);
1311 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1312 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1316 case Intrinsic::vp_load:
1317 case Intrinsic::vp_store:
1318 case Intrinsic::experimental_vp_strided_load:
1319 case Intrinsic::experimental_vp_strided_store: {
1321 unsigned IID = CI->getIntrinsicID();
1322 bool IsWrite = CI->getType()->isVoidTy();
1323 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1325 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1326 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1328 Value *Stride =
nullptr;
1329 if (IID == Intrinsic::experimental_vp_strided_store ||
1330 IID == Intrinsic::experimental_vp_strided_load) {
1331 Stride = VPI->getOperand(PtrOpNo + 1);
1335 unsigned PointerAlign =
Alignment.valueOrOne().value();
1340 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1341 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1345 case Intrinsic::vp_gather:
1346 case Intrinsic::vp_scatter: {
1348 unsigned IID = CI->getIntrinsicID();
1349 bool IsWrite = IID == Intrinsic::vp_scatter;
1350 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1352 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1353 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1355 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1356 VPI->getMaskParam(),
1357 VPI->getVectorLengthParam());
1363 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1367 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1368 if (!Opts.asan_instrument_byval || !CI->isByValArgument(ArgNo) ||
1369 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1371 Type *Ty = CI->getParamByValType(ArgNo);
1387 if (!Cmp->isRelational())
1401 if (BO->getOpcode() != Instruction::Sub)
1414 if (!
G->hasInitializer())
1417 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1424 Type *Ty = V->getType();
1425 if (Ty->isPtrOrPtrVectorTy())
1431bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1433 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1448 "invalid vector pointer pair instrumentation operands");
1449 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1450 Index != NumElements; ++Index) {
1451 Value *ScalarParam[2] = {
1458 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1465 RTCI.createRuntimeCall(IRB,
F, Param);
1472 TypeSize TypeStoreSize,
bool IsWrite,
1473 Value *SizeArgument,
bool UseCalls,
1474 uint32_t Exp, RuntimeCallInserter &RTCI) {
1479 switch (FixedSize) {
1485 if (!Alignment || *Alignment >= Granularity ||
1486 *Alignment >= FixedSize / 8)
1487 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1488 FixedSize, IsWrite,
nullptr, UseCalls,
1492 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1493 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1496void AddressSanitizer::instrumentMaskedLoadOrStore(
1499 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1500 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1501 RuntimeCallInserter &RTCI) {
1503 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1504 auto Zero = ConstantInt::get(IntptrTy, 0);
1512 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1514 IB.SetInsertPoint(LoopInsertBefore);
1516 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1519 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1520 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1522 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1527 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1531 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1532 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1533 if (MaskElemC->isZero())
1539 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1540 MaskElem, &*IRB.GetInsertPoint(), false);
1541 IRB.SetInsertPoint(ThenTerm);
1544 Value *InstrumentedAddress;
1547 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1548 "Expected vector of pointer.");
1549 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1550 }
else if (Stride) {
1557 Alignment, Granularity, ElemTypeSize, IsWrite,
1558 SizeArgument, UseCalls, Exp, RTCI);
1565 RuntimeCallInserter &RTCI) {
1566 Value *Addr =
O.getPtr();
1579 uint32_t
Exp = Opts.asan_force_experiment;
1581 if (Opts.asan_opt && Opts.asan_opt_globals) {
1586 (!Opts.asan_initialization_order || GlobalIsLinkerInitialized(
G)) &&
1587 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1588 NumOptimizedAccessesToGlobalVar++;
1593 if (Opts.asan_opt && Opts.asan_opt_stack) {
1596 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1597 NumOptimizedAccessesToStackVar++;
1603 NumInstrumentedWrites++;
1605 NumInstrumentedReads++;
1607 if (
O.MaybeByteOffset) {
1612 if (TargetTriple.isRISCV()) {
1617 static_cast<unsigned>(LongSize)) {
1626 unsigned Granularity = 1 << Mapping.Scale;
1628 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1629 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1630 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1631 UseCalls, Exp, RTCI);
1634 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1635 UseCalls, Exp, RTCI);
1640 Value *Addr,
bool IsWrite,
1641 size_t AccessSizeIndex,
1642 Value *SizeArgument,
1644 RuntimeCallInserter &RTCI) {
1650 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1651 {Addr, SizeArgument});
1653 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1654 {Addr, SizeArgument, ExpVal});
1657 Call = RTCI.createRuntimeCall(
1658 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1660 Call = RTCI.createRuntimeCall(
1661 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1670 uint32_t TypeStoreSize) {
1671 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1673 Value *LastAccessedByte =
1674 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1676 if (TypeStoreSize / 8 > 1)
1678 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1681 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1686Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1688 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1695 return InsertBefore;
1700 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1702 Value *AddrSpaceZeroLanding =
1705 return InsertBefore;
1720 Trm->getParent()->setName(
"asan.report");
1731void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1734 uint32_t TypeStoreSize,
bool IsWrite,
1735 Value *SizeArgument,
bool UseCalls,
1737 RuntimeCallInserter &RTCI) {
1738 if (TargetTriple.isAMDGPU()) {
1739 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1740 TypeStoreSize, IsWrite, SizeArgument);
1748 if (UseCalls && Opts.asan_optimize_callbacks) {
1749 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1752 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
1759 RTCI.createRuntimeCall(
1760 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1762 RTCI.createRuntimeCall(
1763 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1764 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
1771 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1773 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
1778 size_t Granularity = 1ULL << Mapping.Scale;
1782 (Opts.asan_always_slow_path || (TypeStoreSize < 8 * Granularity));
1784 if (TargetTriple.isAMDGCN()) {
1786 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1789 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
1790 }
else if (GenSlowPath) {
1797 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1812 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
1821void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1823 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
1824 uint32_t Exp, RuntimeCallInserter &RTCI) {
1832 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
1835 RTCI.createRuntimeCall(
1836 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
1850void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
1855 Value *ModuleNameAddr =
1863 for (
auto &BB : GlobalInit)
1875void ModuleAddressSanitizer::createInitializerPoisonCalls() {
1895 poisonOneInitializer(*
F);
1901ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
1906 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
1918bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
1919 Type *Ty =
G->getValueType();
1922 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
1924 if (!Ty->
isSized())
return false;
1925 if (!
G->hasInitializer())
return false;
1932 if (
G->isThreadLocal())
return false;
1934 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
1940 if (!TargetTriple.isOSBinFormatCOFF()) {
1941 if (!
G->hasExactDefinition() ||
G->hasComdat())
1945 if (
G->isInterposable())
1949 if (
G->hasAvailableExternallyLinkage())
1956 switch (
C->getSelectionKind()) {
1967 if (
G->hasSection()) {
1977 if (Section ==
"llvm.metadata")
return false;
1984 if (
Section.starts_with(
".preinit_array") ||
1985 Section.starts_with(
".init_array") ||
1986 Section.starts_with(
".fini_array")) {
1992 if (TargetTriple.isOSBinFormatELF()) {
2006 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2007 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2012 if (TargetTriple.isOSBinFormatMachO()) {
2014 unsigned TAA = 0, StubSize = 0;
2017 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2022 if (ParsedSegment ==
"__OBJC" ||
2023 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2035 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2048 if (CompileKernel) {
2051 if (
G->getName().starts_with(
"__"))
2061bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2062 if (!TargetTriple.isOSBinFormatMachO())
2065 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2067 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2069 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2071 if (TargetTriple.isDriverKit())
2073 if (TargetTriple.isXROS())
2079StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2080 switch (TargetTriple.getObjectFormat()) {
2090 "ModuleAddressSanitizer not implemented for object file format");
2097void ModuleAddressSanitizer::initializeCallbacks() {
2103 AsanUnpoisonGlobals =
2107 AsanRegisterGlobals = Inserter.insertFunction(
2109 AsanUnregisterGlobals = Inserter.insertFunction(
2114 AsanRegisterImageGlobals = Inserter.insertFunction(
2116 AsanUnregisterImageGlobals = Inserter.insertFunction(
2119 AsanRegisterElfGlobals =
2121 IntptrTy, IntptrTy, IntptrTy);
2122 AsanUnregisterElfGlobals =
2124 IntptrTy, IntptrTy, IntptrTy);
2129void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2134 if (!
G->hasName()) {
2138 G->setName(
genName(
"anon_global"));
2141 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2142 std::string
Name = std::string(
G->getName());
2143 Name += InternalSuffix;
2144 C =
M.getOrInsertComdat(Name);
2146 C =
M.getOrInsertComdat(
G->getName());
2152 if (TargetTriple.isOSBinFormatCOFF()) {
2154 if (
G->hasPrivateLinkage())
2167ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2169 auto Linkage = TargetTriple.isOSBinFormatMachO()
2175 Metadata->setSection(getGlobalMetadataSection());
2182Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2186 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2194void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2198 auto &
DL =
M.getDataLayout();
2201 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2202 Constant *Initializer = MetadataInitializers[i];
2206 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2212 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2214 "global metadata will not be padded appropriately");
2217 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2222 if (!MetadataGlobals.empty())
2226void ModuleAddressSanitizer::instrumentGlobalsELF(
2229 const std::string &UniqueModuleId) {
2236 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2239 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2242 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2244 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2247 if (UseComdatForGlobalsGC)
2248 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2253 if (!MetadataGlobals.empty())
2270 "__start_" + getGlobalMetadataSection());
2274 "__stop_" + getGlobalMetadataSection());
2288 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2295void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2306 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2307 Constant *Initializer = MetadataInitializers[i];
2313 auto LivenessBinder =
2318 Twine(
"__asan_binder_") +
G->getName());
2319 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2320 LivenessGlobals[i] = Liveness;
2327 if (!LivenessGlobals.empty())
2349 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2354void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2358 unsigned N = ExtendedGlobals.
size();
2368 if (Mapping.Scale > 3)
2374 ConstantInt::get(IntptrTy,
N)});
2380 IrbDtor.CreateCall(AsanUnregisterGlobals,
2382 ConstantInt::get(IntptrTy,
N)});
2391void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2396 if (CompileKernel) {
2397 for (
auto &GA :
M.aliases()) {
2399 AliasedGlobalExclusions.
insert(GV);
2404 for (
auto &
G :
M.globals()) {
2405 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2409 size_t n = GlobalsToChange.
size();
2410 auto &
DL =
M.getDataLayout();
2424 IntptrTy, IntptrTy, IntptrTy);
2428 for (
size_t i = 0; i < n; i++) {
2432 if (
G->hasSanitizerMetadata())
2433 MD =
G->getSanitizerMetadata();
2438 std::string NameForGlobal =
G->getName().str();
2443 Type *Ty =
G->getValueType();
2444 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2457 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2458 G->getThreadLocalMode(),
G->getAddressSpace());
2468 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2471 if (Seq && Seq->isCString())
2472 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2479 G->replaceAllUsesWith(NewGlobal);
2481 G->eraseFromParent();
2482 NewGlobals[i] = NewGlobal;
2487 bool CanUsePrivateAliases =
2488 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2489 TargetTriple.isOSBinFormatWasm();
2490 if (CanUsePrivateAliases && UsePrivateAlias) {
2493 InstrumentedGlobal =
2500 }
else if (UseOdrIndicator) {
2503 auto *ODRIndicatorSym =
2512 ODRIndicatorSym->setAlignment(
Align(1));
2519 ConstantInt::get(IntptrTy, SizeInBytes),
2520 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2523 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2528 Initializers[i] = Initializer;
2534 for (
size_t i = 0; i < n; i++) {
2536 if (
G->getName().empty())
continue;
2541 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2548 }
else if (n == 0) {
2551 *CtorComdat = TargetTriple.isOSBinFormatELF();
2553 *CtorComdat =
false;
2554 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2555 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2556 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2557 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2559 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2564 if (Opts.asan_initialization_order)
2565 createInitializerPoisonCalls();
2571ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2572 constexpr uint64_t kMaxRZ = 1 << 18;
2573 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2576 if (SizeInBytes <= MinRZ / 2) {
2580 RZ = MinRZ - SizeInBytes;
2583 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2586 if (SizeInBytes % MinRZ)
2587 RZ += MinRZ - (SizeInBytes % MinRZ);
2590 assert((RZ + SizeInBytes) % MinRZ == 0);
2595int ModuleAddressSanitizer::GetAsanVersion()
const {
2596 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2597 bool isAndroid =
M.getTargetTriple().isAndroid();
2601 Version += (LongSize == 32 && isAndroid);
2616bool ModuleAddressSanitizer::instrumentModule() {
2617 initializeCallbacks();
2625 if (CompileKernel) {
2630 std::string AsanVersion = std::to_string(GetAsanVersion());
2631 std::string VersionCheckName =
2633 std::tie(AsanCtorFunction, std::ignore) =
2636 {}, VersionCheckName);
2640 bool CtorComdat =
true;
2641 if (Opts.asan_globals) {
2643 if (AsanCtorFunction) {
2644 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2645 instrumentGlobals(IRB, &CtorComdat);
2648 instrumentGlobals(IRB, &CtorComdat);
2657 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2658 if (AsanCtorFunction) {
2662 if (AsanDtorFunction) {
2667 if (AsanCtorFunction)
2669 if (AsanDtorFunction)
2680 for (
int Exp = 0;
Exp < 2;
Exp++) {
2681 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2682 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2683 const std::string ExpStr =
Exp ?
"exp_" :
"";
2684 const std::string EndingStr = Recover ?
"_noabort" :
"";
2694 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2695 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2696 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2699 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2703 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2704 Inserter.insertFunction(
2705 (Opts.asan_memory_access_callback_prefix + ExpStr + TypeStr +
2711 AccessSizeIndex++) {
2712 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2713 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2714 Inserter.insertFunction(
2718 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2719 Inserter.insertFunction(
2720 (Opts.asan_memory_access_callback_prefix + ExpStr + Suffix +
2728 const std::string MemIntrinCallbackPrefix =
2729 (CompileKernel && !Opts.asan_kernel_mem_intrinsic_prefix)
2731 : Opts.asan_memory_access_callback_prefix.str();
2732 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2733 PtrTy, PtrTy, PtrTy, IntptrTy);
2734 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2735 PtrTy, PtrTy, PtrTy, IntptrTy);
2737 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
2742 AsanHandleNoReturnFunc =
2745 AsanPtrCmpFunction =
2747 AsanPtrSubFunction =
2749 if (Mapping.InGlobal)
2750 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
2753 AMDGPUAddressShared =
2759bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2767 if (
F.getName().contains(
" load]")) {
2777bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
2783 if (Mapping.InGlobal) {
2784 if (Opts.asan_with_ifunc_suppress_remat) {
2791 LocalDynamicShadow =
2792 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
2794 LocalDynamicShadow =
2798 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
2800 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
2805void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
2810 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
2814 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
2820 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
2822 for (
Value *Arg :
II->args()) {
2825 "non-static alloca arg to localescape");
2826 ProcessedAllocas[AI] =
false;
2835void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
2841 for (
Value *Operand : CatchPad->arg_operands())
2843 ProcessedAllocas[AI] =
false;
2849bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
2850 bool ShouldInstrument = Opts.asan_debug_min < 0 || Opts.asan_debug_max < 0 ||
2851 (Instrumented >= Opts.asan_debug_min &&
2852 Instrumented <= Opts.asan_debug_max);
2854 return !ShouldInstrument;
2857bool AddressSanitizer::instrumentFunction(
Function &
F,
2860 bool FunctionModified =
false;
2863 if (
F.hasFnAttribute(Attribute::Naked))
2864 return FunctionModified;
2869 if (maybeInsertAsanInitAtFunctionEntry(
F))
2870 FunctionModified =
true;
2873 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
2875 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2876 return FunctionModified;
2880 initializeCallbacks(TLI);
2882 FunctionStateRAII CleanupObj(
this);
2884 RuntimeCallInserter RTCI(
F);
2886 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
2890 markEscapedLocalAllocas(
F);
2892 if (TargetTriple.isOSWindows())
2893 markCatchParametersAsUninteresting(
F);
2905 for (
auto &BB :
F) {
2907 TempsToInstrument.
clear();
2908 int NumInsnsPerBB = 0;
2909 for (
auto &Inst : BB) {
2910 if (LooksLikeCodeInBug11395(&Inst))
return false;
2917 if (!InterestingOperands.
empty()) {
2918 for (
auto &Operand : InterestingOperands) {
2919 if (Opts.asan_opt && Opts.asan_opt_same_temp) {
2920 Value *Ptr = Operand.getPtr();
2924 if (Operand.MaybeMask) {
2925 if (TempsToInstrument.
count(Ptr))
2928 if (!TempsToInstrument.
insert(Ptr).second)
2932 OperandsToInstrument.
push_back(Operand);
2935 }
else if (((Opts.asan_detect_invalid_pointer_pair ||
2936 Opts.asan_detect_invalid_pointer_cmp) &&
2938 ((Opts.asan_detect_invalid_pointer_pair ||
2939 Opts.asan_detect_invalid_pointer_sub) &&
2941 PointerComparisonsOrSubtracts.
push_back(&Inst);
2949 TempsToInstrument.
clear();
2956 if (NumInsnsPerBB >= Opts.asan_max_ins_per_bb)
2961 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
2962 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
2963 (
unsigned)InstrumentationWithCallsThreshold);
2968 int NumInstrumented = 0;
2969 for (
auto &Operand : OperandsToInstrument) {
2970 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2971 instrumentMop(ObjSizeVis, Operand, UseCalls,
2972 F.getDataLayout(), RTCI);
2973 FunctionModified =
true;
2975 for (
auto *Inst : IntrinToInstrument) {
2976 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2977 instrumentMemIntrinsic(Inst, RTCI);
2978 FunctionModified =
true;
2981 FunctionStackPoisoner FSP(
F, *
this, RTCI);
2982 bool ChangedStack = FSP.runOnFunction();
2986 for (
auto *CI : NoReturnCalls) {
2988 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
2991 for (
auto *Inst : PointerComparisonsOrSubtracts) {
2992 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
2995 if (ChangedStack || !NoReturnCalls.empty())
2996 FunctionModified =
true;
2998 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3001 return FunctionModified;
3007bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3008 if (LongSize != 32)
return false;
3017void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
3021 const char *MallocNameTemplate =
3026 std::string Suffix =
itostr(Index);
3027 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3028 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3029 AsanStackFreeFunc[
Index] =
3034 if (ASan.UseAfterScope) {
3035 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3037 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3041 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3042 0xf3, 0xf5, 0xf8}) {
3043 std::ostringstream
Name;
3045 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3046 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3050 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3052 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3058 size_t Begin,
size_t End,
3060 Value *ShadowBase) {
3064 const size_t LargestStoreSizeInBytes =
3065 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3067 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3073 for (
size_t i = Begin; i <
End;) {
3074 if (!ShadowMask[i]) {
3080 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3082 while (StoreSizeInBytes >
End - i)
3083 StoreSizeInBytes /= 2;
3086 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3087 while (j <= StoreSizeInBytes / 2)
3088 StoreSizeInBytes /= 2;
3092 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3094 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3096 Val = (Val << 8) | ShadowBytes[i + j];
3099 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3105 i += StoreSizeInBytes;
3112 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3117 size_t Begin,
size_t End,
3120 size_t Done = Begin;
3121 for (
size_t i = Begin, j = Begin + 1; i <
End; i =
j++) {
3122 if (!ShadowMask[i]) {
3126 uint8_t Val = ShadowBytes[i];
3127 if (!AsanSetShadowFunc[Val])
3131 for (;
j <
End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3134 if (j - i >= ASan.MaxInlinePoisoningSize) {
3135 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3136 RTCI.createRuntimeCall(
3137 IRB, AsanSetShadowFunc[Val],
3138 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3139 ConstantInt::get(IntptrTy, j - i)});
3144 copyToShadowInline(ShadowMask, ShadowBytes,
Done,
End, IRB, ShadowBase);
3152 for (
int i = 0;; i++, MaxSize *= 2)
3153 if (LocalStackSize <= MaxSize)
return i;
3157void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3159 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3167 if (Arg.hasByValAttr()) {
3168 Type *Ty = Arg.getParamByValType();
3170 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3174 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3177 Arg.replaceAllUsesWith(AI);
3179 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3180 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3188 Value *ValueIfFalse) {
3191 PHI->addIncoming(ValueIfFalse, CondBlock);
3193 PHI->addIncoming(ValueIfTrue, ThenBlock);
3197Value *FunctionStackPoisoner::createAllocaForLayout(
3206 nullptr,
"MyAlloca");
3209 assert((Opts.asan_realign_stack & (Opts.asan_realign_stack - 1)) == 0);
3211 std::max(
L.FrameAlignment,
uint64_t(Opts.asan_realign_stack));
3216void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3219 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3224void FunctionStackPoisoner::processDynamicAllocas() {
3225 if (!Opts.asan_instrument_dynamic_allocas || DynamicAllocaVec.
empty()) {
3231 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3234 assert(ASan.isInterestingAlloca(*APC.AI));
3235 assert(!APC.AI->isStaticAlloca());
3238 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3245 createDynamicAllocasInitStorage();
3246 for (
auto &AI : DynamicAllocaVec)
3247 handleDynamicAllocaCall(AI);
3248 unpoisonDynamicAllocas();
3260 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3277 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3282 bool IsArgInitViaCast =
3287 Val == It->getPrevNode();
3288 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3292 if (IsArgInitViaCast)
3307 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3310 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3314 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3317 auto MetadataString =
3319 if (MetadataString->getString() ==
"alloca_name_altered")
3328void FunctionStackPoisoner::processStaticAllocas() {
3329 if (AllocaVec.
empty()) {
3334 int StackMallocIdx = -1;
3336 if (
auto SP =
F.getSubprogram())
3337 EntryDebugLocation =
3346 auto InsBeforeB = InsBefore->
getParent();
3347 assert(InsBeforeB == &
F.getEntryBlock());
3348 for (
auto *AI : StaticAllocasToMoveUp)
3359 ArgInitInst->moveBefore(InsBefore->
getIterator());
3362 if (LocalEscapeCall)
3370 ASan.getAllocaSizeInBytes(*AI),
3381 uint64_t Granularity = 1ULL << Mapping.Scale;
3382 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3388 for (
auto &
Desc : SVD)
3392 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3395 assert(ASan.isInterestingAlloca(*APC.AI));
3396 assert(APC.AI->isStaticAlloca());
3401 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3402 if (LifetimeLoc->getFile() == FnLoc->getFile())
3403 if (
unsigned Line = LifetimeLoc->getLine())
3404 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3410 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3412 bool DoStackMalloc =
3415 bool DoDynamicAlloca = Opts.asan_stack_dynamic_alloca;
3422 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3423 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3425 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3426 Value *StaticAlloca =
3427 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3429 Value *FakeStackPtr;
3430 Value *FakeStackInt;
3431 Value *LocalStackBase;
3432 Value *LocalStackBaseAlloca;
3435 if (DoStackMalloc) {
3436 LocalStackBaseAlloca =
3437 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3444 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3454 Value *FakeStackValue =
3455 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3456 ConstantInt::get(IntptrTy, LocalStackSize));
3458 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3459 Term, ConstantInt::get(IntptrTy, 0));
3467 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3468 ConstantInt::get(IntptrTy, LocalStackSize));
3471 Value *NoFakeStack =
3476 Value *AllocaValue =
3477 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3481 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3482 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3490 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3491 LocalStackBaseAlloca = LocalStackBase;
3496 for (
const auto &
Desc : SVD) {
3500 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3513 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3521 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3528 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3531 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3533 if (!StaticAllocaPoisonCallVec.empty()) {
3537 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3540 size_t Begin =
Desc.Offset /
L.Granularity;
3541 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3544 copyToShadow(ShadowAfterScope,
3545 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin,
End,
3551 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3554 if (
I->isLifetimeStartOrEnd())
3555 I->eraseFromParent();
3568 if (DoStackMalloc) {
3569 assert(StackMallocIdx >= 0);
3586 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3588 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3590 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3592 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3594 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3595 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3596 IRBPoison.CreateStore(
3598 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3601 RTCI.createRuntimeCall(
3602 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3603 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3607 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3609 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3614 for (
auto *AI : AllocaVec)
3622 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3623 RTCI.createRuntimeCall(
3624 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3625 {AddrArg, SizeArg});
3636void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3644 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3678 ConstantInt::get(IntptrTy,
Alignment.value()));
3681 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3692 if (
I->isLifetimeStartOrEnd())
3693 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.
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.
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.