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 const Triple &TargetTriple,
int LongSize,
355 bool IsKasan, uint64_t *ShadowBase,
356 int *MappingScale,
bool *OrShadowOffset) {
359 TargetTriple, LongSize, IsKasan);
360 *ShadowBase = Mapping.Offset;
361 *MappingScale = Mapping.Scale;
362 *OrShadowOffset = Mapping.OrShadowOffset;
383 if (!
F.getMemoryEffects()
385 .doesNotAccessMemory() &&
387 F.setMemoryEffects(
F.getMemoryEffects() |
395 F.setMemoryEffects(
F.getMemoryEffects() |
400 if (
A.hasAttribute(Attribute::WriteOnly)) {
401 A.removeAttr(Attribute::WriteOnly);
409 F.addFnAttr(Attribute::NoBuiltin);
430 return std::max(32U, 1U << MappingScale);
446class AsanFunctionInserter {
448 AsanFunctionInserter(
Module &M) :
M(
M) {}
450 template <
typename... ArgTypes>
451 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
452 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
465class RuntimeCallInserter {
467 bool TrackInsertedCalls =
false;
471 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
473 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
474 if (isScopedEHPersonality(Personality))
475 TrackInsertedCalls = true;
479 ~RuntimeCallInserter() {
480 if (InsertedCalls.
empty())
482 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
484 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
485 for (CallInst *CI : InsertedCalls) {
487 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
489 "Instruction doesn't belong to the expected Function!");
497 if (Colors.
size() != 1) {
499 "Instruction's BasicBlock is not monochromatic");
506 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
510 OB, CI->getIterator());
511 NewCall->copyMetadata(*CI);
512 CI->replaceAllUsesWith(NewCall);
513 CI->eraseFromParent();
518 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
520 const Twine &
Name =
"") {
523 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
524 if (TrackInsertedCalls)
525 InsertedCalls.push_back(Inst);
531struct AddressSanitizer {
532 AddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
533 const StackSafetyGlobalInfo *SSGI,
534 int InstrumentationWithCallsThreshold,
535 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
536 bool Recover =
false,
bool UseAfterScope =
false,
538 AsanDetectStackUseAfterReturnMode::Runtime)
539 : Opts(Opts),
M(
M), Inserter(
M),
540 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
541 Recover(
valueOr(Opts.asan_recover, Recover)),
542 UseAfterScope(UseAfterScope || Opts.asan_use_after_scope),
543 UseAfterReturn(Opts.asan_use_after_return.value_or(UseAfterReturn)),
544 SSGI(SSGI), InstrumentationWithCallsThreshold(
545 Opts.asan_instrumentation_with_call_threshold.value_or(
546 InstrumentationWithCallsThreshold)),
547 MaxInlinePoisoningSize(Opts.asan_max_inline_poisoning_size.value_or(
548 MaxInlinePoisoningSize)) {
549 C = &(
M.getContext());
550 DL = &
M.getDataLayout();
551 LongSize =
M.getDataLayout().getPointerSizeInBits();
552 IntptrTy = Type::getIntNTy(*
C, LongSize);
553 PtrTy = PointerType::getUnqual(*
C);
554 Int32Ty = Type::getInt32Ty(*
C);
555 TargetTriple =
M.getTargetTriple();
560 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
568 bool isInterestingAlloca(
const AllocaInst &AI);
570 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
572 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
573 const TargetTransformInfo *
TTI);
575 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
576 InterestingMemoryOperand &O,
bool UseCalls,
577 const DataLayout &
DL, RuntimeCallInserter &RTCI);
578 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
579 RuntimeCallInserter &RTCI);
581 Value *Addr, MaybeAlign Alignment,
582 uint32_t TypeStoreSize,
bool IsWrite,
583 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
584 RuntimeCallInserter &RTCI);
585 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
586 Instruction *InsertBefore,
Value *Addr,
587 uint32_t TypeStoreSize,
bool IsWrite,
588 Value *SizeArgument);
591 void instrumentUnusualSizeOrAlignment(Instruction *
I,
592 Instruction *InsertBefore,
Value *Addr,
593 TypeSize TypeStoreSize,
bool IsWrite,
594 Value *SizeArgument,
bool UseCalls,
596 RuntimeCallInserter &RTCI);
597 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
600 MaybeAlign Alignment,
unsigned Granularity,
601 Type *OpType,
bool IsWrite,
602 Value *SizeArgument,
bool UseCalls,
603 uint32_t Exp, RuntimeCallInserter &RTCI);
605 Value *ShadowValue, uint32_t TypeStoreSize);
607 bool IsWrite,
size_t AccessSizeIndex,
608 Value *SizeArgument, uint32_t Exp,
609 RuntimeCallInserter &RTCI);
610 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
612 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
613 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
614 const TargetTransformInfo *
TTI);
615 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
616 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
617 void markEscapedLocalAllocas(
Function &
F);
618 void markCatchParametersAsUninteresting(
Function &
F);
621 friend struct FunctionStackPoisoner;
623 void initializeCallbacks(
const TargetLibraryInfo *TLI);
625 bool LooksLikeCodeInBug11395(Instruction *
I);
626 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
627 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
628 TypeSize TypeStoreSize)
const;
631 struct FunctionStateRAII {
632 AddressSanitizer *
Pass;
634 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
636 "last pass forgot to clear cache");
640 ~FunctionStateRAII() {
641 Pass->LocalDynamicShadow =
nullptr;
642 Pass->ProcessedAllocas.clear();
646 const InstrumentationOptions &Opts;
648 AsanFunctionInserter Inserter;
650 const DataLayout *
DL;
660 ShadowMapping Mapping;
661 FunctionCallee AsanHandleNoReturnFunc;
662 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
670 FunctionCallee AsanErrorCallbackSized[2][2];
671 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
672 FunctionCallee AsanAssumeDereferenceableCallback;
674 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
675 Value *LocalDynamicShadow =
nullptr;
676 const StackSafetyGlobalInfo *SSGI;
677 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
679 FunctionCallee AMDGPUAddressShared;
680 FunctionCallee AMDGPUAddressPrivate;
681 int InstrumentationWithCallsThreshold;
682 uint32_t MaxInlinePoisoningSize;
685class ModuleAddressSanitizer {
687 ModuleAddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
688 bool InsertVersionCheck,
bool CompileKernel =
false,
689 bool Recover =
false,
bool UseGlobalsGC =
true,
690 bool UseOdrIndicator =
true,
693 : Opts(Opts),
M(
M), Inserter(
M),
694 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
695 InsertVersionCheck(
valueOr(Opts.asan_guard_against_version_mismatch,
696 InsertVersionCheck)),
697 Recover(
valueOr(Opts.asan_recover, Recover)),
698 UseGlobalsGC(UseGlobalsGC && Opts.asan_globals_live_support &&
699 !this->CompileKernel),
701 UsePrivateAlias(
valueOr(Opts.asan_use_private_alias, UseOdrIndicator)),
702 UseOdrIndicator(
valueOr(Opts.asan_use_odr_indicator, UseOdrIndicator)),
711 UseCtorComdat(UseGlobalsGC && Opts.asan_with_comdat &&
712 !this->CompileKernel),
713 DestructorKind(Opts.asan_destructor_kind.value_or(DestructorKind)),
714 ConstructorKind(Opts.asan_constructor_kind.value_or(ConstructorKind)) {
715 C = &(
M.getContext());
716 int LongSize =
M.getDataLayout().getPointerSizeInBits();
717 IntptrTy = Type::getIntNTy(*
C, LongSize);
718 PtrTy = PointerType::getUnqual(*
C);
719 TargetTriple =
M.getTargetTriple();
723 assert(this->DestructorKind != AsanDtorKind::Invalid);
726 bool instrumentModule();
729 void initializeCallbacks();
731 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
738 const std::string &UniqueModuleId);
743 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
747 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
748 StringRef OriginalName);
749 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
750 StringRef InternalSuffix);
753 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
754 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
755 bool ShouldUseMachOGlobalsSection()
const;
756 StringRef getGlobalMetadataSection()
const;
757 void poisonOneInitializer(
Function &GlobalInit);
758 void createInitializerPoisonCalls();
759 uint64_t getMinRedzoneSizeForGlobal()
const {
763 int GetAsanVersion()
const;
764 GlobalVariable *getOrCreateModuleName();
766 const InstrumentationOptions &Opts;
768 AsanFunctionInserter Inserter;
770 bool InsertVersionCheck;
773 bool UsePrivateAlias;
774 bool UseOdrIndicator;
782 ShadowMapping Mapping;
783 FunctionCallee AsanPoisonGlobals;
784 FunctionCallee AsanUnpoisonGlobals;
785 FunctionCallee AsanRegisterGlobals;
786 FunctionCallee AsanUnregisterGlobals;
787 FunctionCallee AsanRegisterImageGlobals;
788 FunctionCallee AsanUnregisterImageGlobals;
789 FunctionCallee AsanRegisterElfGlobals;
790 FunctionCallee AsanUnregisterElfGlobals;
792 Function *AsanCtorFunction =
nullptr;
793 Function *AsanDtorFunction =
nullptr;
794 GlobalVariable *ModuleName =
nullptr;
806struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
807 const InstrumentationOptions &Opts;
809 AddressSanitizer &ASan;
810 RuntimeCallInserter &RTCI;
815 ShadowMapping Mapping;
819 SmallVector<Instruction *, 8> RetVec;
823 FunctionCallee AsanSetShadowFunc[0x100] = {};
824 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
825 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
828 struct AllocaPoisonCall {
829 IntrinsicInst *InsBefore;
839 AllocaInst *DynamicAllocaLayout =
nullptr;
840 IntrinsicInst *LocalEscapeCall =
nullptr;
842 bool HasInlineAsm =
false;
843 bool HasReturnsTwiceCall =
false;
846 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
847 RuntimeCallInserter &RTCI)
848 : Opts(ASan.Opts),
F(
F), ASan(ASan), RTCI(RTCI),
850 IntptrTy(ASan.IntptrTy),
852 Mapping(ASan.Mapping),
853 PoisonStack(Opts.asan_stack &&
854 !
F.
getParent()->getTargetTriple().isAMDGPU()) {}
860 if (Opts.asan_redzone_byval_args)
861 copyArgsPassedByValToAllocas();
866 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
868 initializeCallbacks(*
F.getParent());
870 processDynamicAllocas();
871 processStaticAllocas();
873 if (Opts.asan_debug_stack) {
882 void copyArgsPassedByValToAllocas();
887 void processStaticAllocas();
888 void processDynamicAllocas();
890 void createDynamicAllocasInitStorage();
895 void visitReturnInst(ReturnInst &RI) {
896 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
903 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
906 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
908 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
918 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
924 RTCI.createRuntimeCall(
925 IRB, AsanAllocasUnpoisonFunc,
926 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
930 void unpoisonDynamicAllocas() {
931 for (Instruction *Ret : RetVec)
932 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
934 for (Instruction *StackRestoreInst : StackRestoreVec)
935 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
936 StackRestoreInst->getOperand(0));
949 void handleDynamicAllocaCall(AllocaInst *AI);
952 void visitAllocaInst(AllocaInst &AI) {
954 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
958 if (AllocaVec.
empty())
974 void visitIntrinsicInst(IntrinsicInst &
II) {
976 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
977 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
978 if (!ASan.UseAfterScope)
980 if (!
II.isLifetimeStartOrEnd())
985 if (!AI || !ASan.isInterestingAlloca(*AI))
995 bool DoPoison = (
ID == Intrinsic::lifetime_end);
996 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
998 StaticAllocaPoisonCallVec.
push_back(APC);
999 else if (Opts.asan_instrument_dynamic_allocas)
1000 DynamicAllocaPoisonCallVec.
push_back(APC);
1003 void visitCallBase(CallBase &CB) {
1005 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1006 HasReturnsTwiceCall |= CI->canReturnTwice();
1011 void initializeCallbacks(
Module &M);
1016 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1018 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1021 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1022 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1027 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1030 Instruction *ThenTerm,
Value *ValueIfFalse);
1037 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1038 OS, MapClassName2PassName);
1040 if (Options.CompileKernel)
1042 if (Options.UseAfterScope)
1043 OS <<
"use-after-scope";
1051 : Options(Options), UseGlobalGC(UseGlobalGC),
1052 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1053 ConstructorKind(ConstructorKind) {}
1062 const InstrumentationOptions &Opts =
1063 M.getContext().getLibraryOptions().get<InstrumentationOptions>();
1064 ModuleAddressSanitizer ModuleSanitizer(Opts, M, Options.InsertVersionCheck,
1065 Options.CompileKernel, Options.Recover,
1066 UseGlobalGC, UseOdrIndicator,
1067 DestructorKind, ConstructorKind);
1078 if (!Opts.asan_debug_func.empty() && Opts.asan_debug_func ==
F.getName())
1080 if (
F.getName().starts_with(
"__asan_"))
1082 if (
F.isPresplitCoroutine())
1084 AddressSanitizer FunctionSanitizer(
1085 Opts, M, SSGI, Options.InstrumentationWithCallsThreshold,
1086 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1087 Options.UseAfterScope, Options.UseAfterReturn);
1090 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1092 Modified |= ModuleSanitizer.instrumentModule();
1113 if (
G->getName().starts_with(
"llvm.") ||
1115 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1117 G->getName().starts_with(
"__llvm_rtti_proxy"))
1133 if (AddrSpace == 3 || AddrSpace == 5)
1143 if (!Opts.asan_instrument_address_spaces.empty())
1144 return is_contained(Opts.asan_instrument_address_spaces, AddrSpace);
1149 return AddrSpace == 0;
1153 if (TargetTriple.isOSDarwin() &&
1157 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1160 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1161 if (Mapping.Offset == 0)
return Shadow;
1164 if (LocalDynamicShadow)
1165 ShadowBase = LocalDynamicShadow;
1167 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1168 if (Mapping.OrShadowOffset)
1169 return IRB.
CreateOr(Shadow, ShadowBase);
1171 return IRB.
CreateAdd(Shadow, ShadowBase);
1176 RuntimeCallInserter &RTCI) {
1179 RTCI.createRuntimeCall(
1185 RTCI.createRuntimeCall(
1191 MI->eraseFromParent();
1195bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1196 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1199 return It->getSecond();
1201 bool IsInteresting =
1212 !(SSGI && SSGI->
isSafe(AI)));
1214 It->second = IsInteresting;
1215 return IsInteresting;
1235 if (Opts.asan_skip_promotable_allocas && !isInterestingAlloca(*AI))
1245void AddressSanitizer::getInterestingMemoryOperands(
1249 if (LocalDynamicShadow ==
I)
1253 if (!Opts.asan_instrument_reads || ignoreAccess(
I, LI->getPointerOperand()))
1255 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1256 LI->getType(), LI->getAlign());
1258 if (!Opts.asan_instrument_writes ||
1259 ignoreAccess(
I,
SI->getPointerOperand()))
1262 SI->getValueOperand()->getType(),
SI->getAlign());
1264 if (!Opts.asan_instrument_atomics ||
1265 ignoreAccess(
I, RMW->getPointerOperand()))
1267 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1268 RMW->getValOperand()->getType(), std::nullopt);
1270 if (!Opts.asan_instrument_atomics ||
1271 ignoreAccess(
I, XCHG->getPointerOperand()))
1273 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1274 XCHG->getCompareOperand()->getType(),
1277 switch (CI->getIntrinsicID()) {
1278 case Intrinsic::masked_load:
1279 case Intrinsic::masked_store:
1280 case Intrinsic::masked_gather:
1281 case Intrinsic::masked_scatter: {
1282 bool IsWrite = CI->getType()->isVoidTy();
1284 unsigned OpOffset = IsWrite ? 1 : 0;
1285 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1288 auto BasePtr = CI->getOperand(OpOffset);
1289 if (ignoreAccess(
I, BasePtr))
1291 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1293 Value *
Mask = CI->getOperand(1 + OpOffset);
1294 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1297 case Intrinsic::masked_expandload:
1298 case Intrinsic::masked_compressstore: {
1299 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1300 unsigned OpOffset = IsWrite ? 1 : 0;
1301 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1303 auto BasePtr = CI->getOperand(OpOffset);
1304 if (ignoreAccess(
I, BasePtr))
1307 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1310 Value *
Mask = CI->getOperand(1 + OpOffset);
1313 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1314 Value *EVL =
IB.CreateAddReduce(ExtMask);
1315 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1316 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1320 case Intrinsic::vp_load:
1321 case Intrinsic::vp_store:
1322 case Intrinsic::experimental_vp_strided_load:
1323 case Intrinsic::experimental_vp_strided_store: {
1325 unsigned IID = CI->getIntrinsicID();
1326 bool IsWrite = CI->getType()->isVoidTy();
1327 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1329 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1330 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1332 Value *Stride =
nullptr;
1333 if (IID == Intrinsic::experimental_vp_strided_store ||
1334 IID == Intrinsic::experimental_vp_strided_load) {
1335 Stride = VPI->getOperand(PtrOpNo + 1);
1339 unsigned PointerAlign =
Alignment.valueOrOne().value();
1344 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1345 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1349 case Intrinsic::vp_gather:
1350 case Intrinsic::vp_scatter: {
1352 unsigned IID = CI->getIntrinsicID();
1353 bool IsWrite = IID == Intrinsic::vp_scatter;
1354 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1356 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1357 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1359 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1360 VPI->getMaskParam(),
1361 VPI->getVectorLengthParam());
1367 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1371 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1372 if (!Opts.asan_instrument_byval || !CI->isByValArgument(ArgNo) ||
1373 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1375 Type *Ty = CI->getParamByValType(ArgNo);
1391 if (!Cmp->isRelational())
1405 if (BO->getOpcode() != Instruction::Sub)
1418 if (!
G->hasInitializer())
1421 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1428 Type *Ty = V->getType();
1429 if (Ty->isPtrOrPtrVectorTy())
1435bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1437 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1452 "invalid vector pointer pair instrumentation operands");
1453 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1454 Index != NumElements; ++Index) {
1455 Value *ScalarParam[2] = {
1462 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1469 RTCI.createRuntimeCall(IRB,
F, Param);
1476 TypeSize TypeStoreSize,
bool IsWrite,
1477 Value *SizeArgument,
bool UseCalls,
1478 uint32_t Exp, RuntimeCallInserter &RTCI) {
1483 switch (FixedSize) {
1489 if (!Alignment || *Alignment >= Granularity ||
1490 *Alignment >= FixedSize / 8)
1491 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1492 FixedSize, IsWrite,
nullptr, UseCalls,
1496 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1497 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1500void AddressSanitizer::instrumentMaskedLoadOrStore(
1503 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1504 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1505 RuntimeCallInserter &RTCI) {
1507 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1508 auto Zero = ConstantInt::get(IntptrTy, 0);
1516 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1518 IB.SetInsertPoint(LoopInsertBefore);
1520 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1523 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1524 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1526 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1531 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1535 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1536 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1537 if (MaskElemC->isZero())
1543 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1544 MaskElem, &*IRB.GetInsertPoint(), false);
1545 IRB.SetInsertPoint(ThenTerm);
1548 Value *InstrumentedAddress;
1551 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1552 "Expected vector of pointer.");
1553 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1554 }
else if (Stride) {
1561 Alignment, Granularity, ElemTypeSize, IsWrite,
1562 SizeArgument, UseCalls, Exp, RTCI);
1569 RuntimeCallInserter &RTCI) {
1570 Value *Addr =
O.getPtr();
1583 uint32_t
Exp = Opts.asan_force_experiment;
1585 if (Opts.asan_opt && Opts.asan_opt_globals) {
1590 (!Opts.asan_initialization_order || GlobalIsLinkerInitialized(
G)) &&
1591 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1592 NumOptimizedAccessesToGlobalVar++;
1597 if (Opts.asan_opt && Opts.asan_opt_stack) {
1600 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1601 NumOptimizedAccessesToStackVar++;
1607 NumInstrumentedWrites++;
1609 NumInstrumentedReads++;
1611 if (
O.MaybeByteOffset) {
1616 if (TargetTriple.isRISCV()) {
1621 static_cast<unsigned>(LongSize)) {
1630 unsigned Granularity = 1 << Mapping.Scale;
1632 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1633 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1634 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1635 UseCalls, Exp, RTCI);
1638 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1639 UseCalls, Exp, RTCI);
1644 Value *Addr,
bool IsWrite,
1645 size_t AccessSizeIndex,
1646 Value *SizeArgument,
1648 RuntimeCallInserter &RTCI) {
1654 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1655 {Addr, SizeArgument});
1657 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1658 {Addr, SizeArgument, ExpVal});
1661 Call = RTCI.createRuntimeCall(
1662 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1664 Call = RTCI.createRuntimeCall(
1665 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1674 uint32_t TypeStoreSize) {
1675 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1677 Value *LastAccessedByte =
1678 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1680 if (TypeStoreSize / 8 > 1)
1682 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1685 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1690Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1692 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1699 return InsertBefore;
1704 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1706 Value *AddrSpaceZeroLanding =
1709 return InsertBefore;
1724 Trm->getParent()->setName(
"asan.report");
1735void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1738 uint32_t TypeStoreSize,
bool IsWrite,
1739 Value *SizeArgument,
bool UseCalls,
1741 RuntimeCallInserter &RTCI) {
1742 if (TargetTriple.isAMDGPU()) {
1743 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1744 TypeStoreSize, IsWrite, SizeArgument);
1752 if (UseCalls && Opts.asan_optimize_callbacks) {
1753 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1756 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
1763 RTCI.createRuntimeCall(
1764 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1766 RTCI.createRuntimeCall(
1767 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1768 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
1775 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1777 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
1782 size_t Granularity = 1ULL << Mapping.Scale;
1786 (Opts.asan_always_slow_path || (TypeStoreSize < 8 * Granularity));
1788 if (TargetTriple.isAMDGCN()) {
1790 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1793 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
1794 }
else if (GenSlowPath) {
1801 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1816 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
1825void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1827 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
1828 uint32_t Exp, RuntimeCallInserter &RTCI) {
1836 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
1839 RTCI.createRuntimeCall(
1840 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
1854void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
1859 Value *ModuleNameAddr =
1867 for (
auto &BB : GlobalInit)
1879void ModuleAddressSanitizer::createInitializerPoisonCalls() {
1899 poisonOneInitializer(*
F);
1905ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
1910 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
1922bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
1923 Type *Ty =
G->getValueType();
1926 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
1928 if (!Ty->
isSized())
return false;
1929 if (!
G->hasInitializer())
return false;
1936 if (
G->isThreadLocal())
return false;
1938 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
1944 if (!TargetTriple.isOSBinFormatCOFF()) {
1945 if (!
G->hasExactDefinition() ||
G->hasComdat())
1949 if (
G->isInterposable())
1953 if (
G->hasAvailableExternallyLinkage())
1960 switch (
C->getSelectionKind()) {
1971 if (
G->hasSection()) {
1981 if (Section ==
"llvm.metadata")
return false;
1988 if (
Section.starts_with(
".preinit_array") ||
1989 Section.starts_with(
".init_array") ||
1990 Section.starts_with(
".fini_array")) {
1996 if (TargetTriple.isOSBinFormatELF()) {
2010 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2011 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2016 if (TargetTriple.isOSBinFormatMachO()) {
2018 unsigned TAA = 0, StubSize = 0;
2021 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2026 if (ParsedSegment ==
"__OBJC" ||
2027 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2039 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2052 if (CompileKernel) {
2055 if (
G->getName().starts_with(
"__"))
2065bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2066 if (!TargetTriple.isOSBinFormatMachO())
2069 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2071 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2073 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2075 if (TargetTriple.isDriverKit())
2077 if (TargetTriple.isXROS())
2083StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2084 switch (TargetTriple.getObjectFormat()) {
2094 "ModuleAddressSanitizer not implemented for object file format");
2101void ModuleAddressSanitizer::initializeCallbacks() {
2107 AsanUnpoisonGlobals =
2111 AsanRegisterGlobals = Inserter.insertFunction(
2113 AsanUnregisterGlobals = Inserter.insertFunction(
2118 AsanRegisterImageGlobals = Inserter.insertFunction(
2120 AsanUnregisterImageGlobals = Inserter.insertFunction(
2123 AsanRegisterElfGlobals =
2125 IntptrTy, IntptrTy, IntptrTy);
2126 AsanUnregisterElfGlobals =
2128 IntptrTy, IntptrTy, IntptrTy);
2133void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2138 if (!
G->hasName()) {
2142 G->setName(
genName(
"anon_global"));
2145 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2146 std::string
Name = std::string(
G->getName());
2147 Name += InternalSuffix;
2148 C =
M.getOrInsertComdat(Name);
2150 C =
M.getOrInsertComdat(
G->getName());
2156 if (TargetTriple.isOSBinFormatCOFF()) {
2158 if (
G->hasPrivateLinkage())
2171ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2173 auto Linkage = TargetTriple.isOSBinFormatMachO()
2179 Metadata->setSection(getGlobalMetadataSection());
2186Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2190 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2198void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2202 auto &
DL =
M.getDataLayout();
2205 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2206 Constant *Initializer = MetadataInitializers[i];
2210 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2216 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2218 "global metadata will not be padded appropriately");
2221 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2226 if (!MetadataGlobals.empty())
2230void ModuleAddressSanitizer::instrumentGlobalsELF(
2233 const std::string &UniqueModuleId) {
2240 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2243 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2246 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2248 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2251 if (UseComdatForGlobalsGC)
2252 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2257 if (!MetadataGlobals.empty())
2274 "__start_" + getGlobalMetadataSection());
2278 "__stop_" + getGlobalMetadataSection());
2292 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2299void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2310 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2311 Constant *Initializer = MetadataInitializers[i];
2317 auto LivenessBinder =
2322 Twine(
"__asan_binder_") +
G->getName());
2323 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2324 LivenessGlobals[i] = Liveness;
2331 if (!LivenessGlobals.empty())
2353 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2358void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2362 unsigned N = ExtendedGlobals.
size();
2372 if (Mapping.Scale > 3)
2378 ConstantInt::get(IntptrTy,
N)});
2384 IrbDtor.CreateCall(AsanUnregisterGlobals,
2386 ConstantInt::get(IntptrTy,
N)});
2395void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2400 if (CompileKernel) {
2401 for (
auto &GA :
M.aliases()) {
2403 AliasedGlobalExclusions.
insert(GV);
2408 for (
auto &
G :
M.globals()) {
2409 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2413 size_t n = GlobalsToChange.
size();
2414 auto &
DL =
M.getDataLayout();
2428 IntptrTy, IntptrTy, IntptrTy);
2432 for (
size_t i = 0; i < n; i++) {
2436 if (
G->hasSanitizerMetadata())
2437 MD =
G->getSanitizerMetadata();
2442 std::string NameForGlobal =
G->getName().str();
2447 Type *Ty =
G->getValueType();
2448 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2461 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2462 G->getThreadLocalMode(),
G->getAddressSpace());
2472 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2475 if (Seq && Seq->isCString())
2476 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2483 G->replaceAllUsesWith(NewGlobal);
2485 G->eraseFromParent();
2486 NewGlobals[i] = NewGlobal;
2491 bool CanUsePrivateAliases =
2492 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2493 TargetTriple.isOSBinFormatWasm();
2494 if (CanUsePrivateAliases && UsePrivateAlias) {
2497 InstrumentedGlobal =
2504 }
else if (UseOdrIndicator) {
2507 auto *ODRIndicatorSym =
2516 ODRIndicatorSym->setAlignment(
Align(1));
2523 ConstantInt::get(IntptrTy, SizeInBytes),
2524 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2527 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2532 Initializers[i] = Initializer;
2538 for (
size_t i = 0; i < n; i++) {
2540 if (
G->getName().empty())
continue;
2545 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2552 }
else if (n == 0) {
2555 *CtorComdat = TargetTriple.isOSBinFormatELF();
2557 *CtorComdat =
false;
2558 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2559 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2560 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2561 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2563 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2568 if (Opts.asan_initialization_order)
2569 createInitializerPoisonCalls();
2575ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2576 constexpr uint64_t kMaxRZ = 1 << 18;
2577 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2580 if (SizeInBytes <= MinRZ / 2) {
2584 RZ = MinRZ - SizeInBytes;
2587 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2590 if (SizeInBytes % MinRZ)
2591 RZ += MinRZ - (SizeInBytes % MinRZ);
2594 assert((RZ + SizeInBytes) % MinRZ == 0);
2599int ModuleAddressSanitizer::GetAsanVersion()
const {
2600 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2601 bool isAndroid =
M.getTargetTriple().isAndroid();
2605 Version += (LongSize == 32 && isAndroid);
2620bool ModuleAddressSanitizer::instrumentModule() {
2621 initializeCallbacks();
2629 if (CompileKernel) {
2634 std::string AsanVersion = std::to_string(GetAsanVersion());
2635 std::string VersionCheckName =
2637 std::tie(AsanCtorFunction, std::ignore) =
2640 {}, VersionCheckName);
2644 bool CtorComdat =
true;
2645 if (Opts.asan_globals) {
2647 if (AsanCtorFunction) {
2648 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2649 instrumentGlobals(IRB, &CtorComdat);
2652 instrumentGlobals(IRB, &CtorComdat);
2661 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2662 if (AsanCtorFunction) {
2666 if (AsanDtorFunction) {
2671 if (AsanCtorFunction)
2673 if (AsanDtorFunction)
2683 const std::string EndingStr = Recover ?
"_noabort" :
"";
2684 AsanAssumeDereferenceableCallback =
M.getOrInsertFunction(
2685 "__asan_report_assume_dereferenceable" + EndingStr,
2690 for (
int Exp = 0;
Exp < 2;
Exp++) {
2691 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2692 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2693 const std::string ExpStr =
Exp ?
"exp_" :
"";
2694 const std::string EndingStr = Recover ?
"_noabort" :
"";
2704 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2705 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2706 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2709 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2713 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2714 Inserter.insertFunction(
2715 (Opts.asan_memory_access_callback_prefix + ExpStr + TypeStr +
2721 AccessSizeIndex++) {
2722 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2723 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2724 Inserter.insertFunction(
2728 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2729 Inserter.insertFunction(
2730 (Opts.asan_memory_access_callback_prefix + ExpStr + Suffix +
2738 const std::string MemIntrinCallbackPrefix =
2739 (CompileKernel && !Opts.asan_kernel_mem_intrinsic_prefix)
2741 : Opts.asan_memory_access_callback_prefix.str();
2742 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2743 PtrTy, PtrTy, PtrTy, IntptrTy);
2744 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2745 PtrTy, PtrTy, PtrTy, IntptrTy);
2747 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
2752 AsanHandleNoReturnFunc =
2755 AsanPtrCmpFunction =
2757 AsanPtrSubFunction =
2759 if (Mapping.InGlobal)
2760 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
2763 AMDGPUAddressShared =
2769bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2777 if (
F.getName().contains(
" load]")) {
2787bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
2793 if (Mapping.InGlobal) {
2794 if (Opts.asan_with_ifunc_suppress_remat) {
2801 LocalDynamicShadow =
2802 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
2804 LocalDynamicShadow =
2808 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
2810 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
2815void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
2820 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
2824 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
2830 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
2832 for (
Value *Arg :
II->args()) {
2835 "non-static alloca arg to localescape");
2836 ProcessedAllocas[AI] =
false;
2845void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
2851 for (
Value *Operand : CatchPad->arg_operands())
2853 ProcessedAllocas[AI] =
false;
2859bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
2860 bool ShouldInstrument = Opts.asan_debug_min < 0 || Opts.asan_debug_max < 0 ||
2861 (Instrumented >= Opts.asan_debug_min &&
2862 Instrumented <= Opts.asan_debug_max);
2864 return !ShouldInstrument;
2867bool AddressSanitizer::instrumentFunction(
Function &
F,
2870 bool FunctionModified =
false;
2873 if (
F.hasFnAttribute(Attribute::Naked))
2874 return FunctionModified;
2879 if (maybeInsertAsanInitAtFunctionEntry(
F))
2880 FunctionModified =
true;
2883 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
2885 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2886 return FunctionModified;
2890 initializeCallbacks(TLI);
2892 FunctionStateRAII CleanupObj(
this);
2894 RuntimeCallInserter RTCI(
F);
2896 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
2900 markEscapedLocalAllocas(
F);
2902 if (TargetTriple.isOSWindows())
2903 markCatchParametersAsUninteresting(
F);
2916 for (
auto &BB :
F) {
2918 TempsToInstrument.
clear();
2919 int NumInsnsPerBB = 0;
2920 for (
auto &Inst : BB) {
2921 if (LooksLikeCodeInBug11395(&Inst))
return false;
2929 if (!InterestingOperands.
empty()) {
2930 for (
auto &Operand : InterestingOperands) {
2931 if (Opts.asan_opt && Opts.asan_opt_same_temp) {
2932 Value *Ptr = Operand.getPtr();
2936 if (Operand.MaybeMask) {
2937 if (TempsToInstrument.
count(Ptr))
2940 if (!TempsToInstrument.
insert(Ptr).second)
2944 OperandsToInstrument.
push_back(Operand);
2947 }
else if (((Opts.asan_detect_invalid_pointer_pair ||
2948 Opts.asan_detect_invalid_pointer_cmp) &&
2950 ((Opts.asan_detect_invalid_pointer_pair ||
2951 Opts.asan_detect_invalid_pointer_sub) &&
2953 PointerComparisonsOrSubtracts.
push_back(&Inst);
2958 }
else if (Opts.asan_instrument_assume_dereferenceable &&
2967 TempsToInstrument.
clear();
2974 if (NumInsnsPerBB >= Opts.asan_max_ins_per_bb)
2979 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
2980 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
2981 (
unsigned)InstrumentationWithCallsThreshold);
2986 int NumInstrumented = 0;
2987 for (
auto &Operand : OperandsToInstrument) {
2988 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2989 instrumentMop(ObjSizeVis, Operand, UseCalls,
2990 F.getDataLayout(), RTCI);
2991 FunctionModified =
true;
2993 for (
auto *Inst : IntrinToInstrument) {
2994 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2995 instrumentMemIntrinsic(Inst, RTCI);
2996 FunctionModified =
true;
2999 FunctionStackPoisoner FSP(
F, *
this, RTCI);
3000 bool ChangedStack = FSP.runOnFunction();
3004 for (
auto *CI : NoReturnCalls) {
3006 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3009 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3010 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3013 for (
auto *AI : DerefAssumptions) {
3015 Value *Ptr = Bundle->Inputs[0];
3028 RTCI.createRuntimeCall(IRB, AsanAssumeDereferenceableCallback,
3029 {AddrLong, SizeExt});
3031 FunctionModified =
true;
3035 if (ChangedStack || !NoReturnCalls.empty())
3036 FunctionModified =
true;
3038 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3041 return FunctionModified;
3047bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3048 if (LongSize != 32)
return false;
3057void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
3061 const char *MallocNameTemplate =
3066 std::string Suffix =
itostr(Index);
3067 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3068 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3069 AsanStackFreeFunc[
Index] =
3074 if (ASan.UseAfterScope) {
3075 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3077 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3081 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3082 0xf3, 0xf5, 0xf8}) {
3083 std::ostringstream
Name;
3085 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3086 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3090 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3092 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3098 size_t Begin,
size_t End,
3100 Value *ShadowBase) {
3104 const size_t LargestStoreSizeInBytes =
3105 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3107 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3113 for (
size_t i = Begin; i <
End;) {
3114 if (!ShadowMask[i]) {
3120 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3122 while (StoreSizeInBytes >
End - i)
3123 StoreSizeInBytes /= 2;
3126 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3127 while (j <= StoreSizeInBytes / 2)
3128 StoreSizeInBytes /= 2;
3132 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3134 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3136 Val = (Val << 8) | ShadowBytes[i + j];
3139 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3145 i += StoreSizeInBytes;
3152 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3157 size_t Begin,
size_t End,
3160 size_t Done = Begin;
3161 for (
size_t i = Begin, j = Begin + 1; i <
End; i =
j++) {
3162 if (!ShadowMask[i]) {
3166 uint8_t Val = ShadowBytes[i];
3167 if (!AsanSetShadowFunc[Val])
3171 for (;
j <
End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3174 if (j - i >= ASan.MaxInlinePoisoningSize) {
3175 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3176 RTCI.createRuntimeCall(
3177 IRB, AsanSetShadowFunc[Val],
3178 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3179 ConstantInt::get(IntptrTy, j - i)});
3184 copyToShadowInline(ShadowMask, ShadowBytes,
Done,
End, IRB, ShadowBase);
3192 for (
int i = 0;; i++, MaxSize *= 2)
3193 if (LocalStackSize <= MaxSize)
return i;
3197void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3199 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3207 if (Arg.hasByValAttr()) {
3208 Type *Ty = Arg.getParamByValType();
3210 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3214 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3217 Arg.replaceAllUsesWith(AI);
3219 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3220 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3228 Value *ValueIfFalse) {
3231 PHI->addIncoming(ValueIfFalse, CondBlock);
3233 PHI->addIncoming(ValueIfTrue, ThenBlock);
3237Value *FunctionStackPoisoner::createAllocaForLayout(
3246 nullptr,
"MyAlloca");
3249 assert((Opts.asan_realign_stack & (Opts.asan_realign_stack - 1)) == 0);
3251 std::max(
L.FrameAlignment,
uint64_t(Opts.asan_realign_stack));
3256void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3259 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3264void FunctionStackPoisoner::processDynamicAllocas() {
3265 if (!Opts.asan_instrument_dynamic_allocas || DynamicAllocaVec.
empty()) {
3271 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3274 assert(ASan.isInterestingAlloca(*APC.AI));
3275 assert(!APC.AI->isStaticAlloca());
3278 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3285 createDynamicAllocasInitStorage();
3286 for (
auto &AI : DynamicAllocaVec)
3287 handleDynamicAllocaCall(AI);
3288 unpoisonDynamicAllocas();
3300 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3317 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3322 bool IsArgInitViaCast =
3327 Val == It->getPrevNode();
3328 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3332 if (IsArgInitViaCast)
3347 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3350 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3354 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3357 auto MetadataString =
3359 if (MetadataString->getString() ==
"alloca_name_altered")
3368void FunctionStackPoisoner::processStaticAllocas() {
3369 if (AllocaVec.
empty()) {
3374 int StackMallocIdx = -1;
3376 if (
auto SP =
F.getSubprogram())
3377 EntryDebugLocation =
3386 auto InsBeforeB = InsBefore->
getParent();
3387 assert(InsBeforeB == &
F.getEntryBlock());
3388 for (
auto *AI : StaticAllocasToMoveUp)
3399 ArgInitInst->moveBefore(InsBefore->
getIterator());
3402 if (LocalEscapeCall)
3410 ASan.getAllocaSizeInBytes(*AI),
3421 uint64_t Granularity = 1ULL << Mapping.Scale;
3422 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3428 for (
auto &
Desc : SVD)
3432 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3435 assert(ASan.isInterestingAlloca(*APC.AI));
3436 assert(APC.AI->isStaticAlloca());
3441 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3442 if (LifetimeLoc->getFile() == FnLoc->getFile())
3443 if (
unsigned Line = LifetimeLoc->getLine())
3444 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3450 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3452 bool DoStackMalloc =
3455 bool DoDynamicAlloca = Opts.asan_stack_dynamic_alloca;
3462 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3463 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3465 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3466 Value *StaticAlloca =
3467 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3469 Value *FakeStackPtr;
3470 Value *FakeStackInt;
3471 Value *LocalStackBase;
3472 Value *LocalStackBaseAlloca;
3475 if (DoStackMalloc) {
3476 LocalStackBaseAlloca =
3477 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3484 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3494 Value *FakeStackValue =
3495 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3496 ConstantInt::get(IntptrTy, LocalStackSize));
3498 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3499 Term, ConstantInt::get(IntptrTy, 0));
3507 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3508 ConstantInt::get(IntptrTy, LocalStackSize));
3511 Value *NoFakeStack =
3516 Value *AllocaValue =
3517 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3521 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3522 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3530 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3531 LocalStackBaseAlloca = LocalStackBase;
3536 for (
const auto &
Desc : SVD) {
3540 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3553 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3561 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3568 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3571 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3573 if (!StaticAllocaPoisonCallVec.empty()) {
3577 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3580 size_t Begin =
Desc.Offset /
L.Granularity;
3581 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3584 copyToShadow(ShadowAfterScope,
3585 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin,
End,
3591 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3594 if (
I->isLifetimeStartOrEnd())
3595 I->eraseFromParent();
3608 if (DoStackMalloc) {
3609 assert(StackMallocIdx >= 0);
3626 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3628 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3630 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3632 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3634 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3635 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3636 IRBPoison.CreateStore(
3638 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3641 RTCI.createRuntimeCall(
3642 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3643 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3647 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3649 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3654 for (
auto *AI : AllocaVec)
3662 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3663 RTCI.createRuntimeCall(
3664 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3665 {AddrArg, SizeArg});
3676void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3684 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3718 ConstantInt::get(IntptrTy,
Alignment.value()));
3721 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3732 if (
I->isLifetimeStartOrEnd())
3733 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.
This is an important class for using LLVM in a threaded context.
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 getAddressSanitizerParams(const LLVMContext &Ctx, const Triple &TargetTriple, int LongSize, bool IsKasan, uint64_t *ShadowBase, int *MappingScale, bool *OrShadowOffset)
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.
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.