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 *ShadowBase = Mapping.Offset;
360 *MappingScale = Mapping.Scale;
361 *OrShadowOffset = Mapping.OrShadowOffset;
382 if (!
F.getMemoryEffects()
384 .doesNotAccessMemory() &&
386 F.setMemoryEffects(
F.getMemoryEffects() |
394 F.setMemoryEffects(
F.getMemoryEffects() |
399 if (
A.hasAttribute(Attribute::WriteOnly)) {
400 A.removeAttr(Attribute::WriteOnly);
408 F.addFnAttr(Attribute::NoBuiltin);
429 return std::max(32U, 1U << MappingScale);
445class AsanFunctionInserter {
447 AsanFunctionInserter(
Module &M) :
M(
M) {}
449 template <
typename... ArgTypes>
450 FunctionCallee insertFunction(StringRef Name, ArgTypes &&...Args) {
451 return M.getOrInsertFunction(Name, std::forward<ArgTypes>(Args)...);
464class RuntimeCallInserter {
466 bool TrackInsertedCalls =
false;
470 RuntimeCallInserter(
Function &Fn) : OwnerFn(&Fn) {
472 auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
473 if (isScopedEHPersonality(Personality))
474 TrackInsertedCalls = true;
478 ~RuntimeCallInserter() {
479 if (InsertedCalls.
empty())
481 assert(TrackInsertedCalls &&
"Calls were wrongly tracked");
483 DenseMap<BasicBlock *, ColorVector> BlockColors =
colorEHFunclets(*OwnerFn);
484 for (CallInst *CI : InsertedCalls) {
486 assert(BB &&
"Instruction doesn't belong to a BasicBlock");
488 "Instruction doesn't belong to the expected Function!");
496 if (Colors.
size() != 1) {
498 "Instruction's BasicBlock is not monochromatic");
505 if (EHPadIt != Color->end() && EHPadIt->isEHPad()) {
509 OB, CI->getIterator());
510 NewCall->copyMetadata(*CI);
511 CI->replaceAllUsesWith(NewCall);
512 CI->eraseFromParent();
517 CallInst *createRuntimeCall(
IRBuilder<> &IRB, FunctionCallee Callee,
519 const Twine &
Name =
"") {
522 CallInst *Inst = IRB.
CreateCall(Callee, Args, Name,
nullptr);
523 if (TrackInsertedCalls)
524 InsertedCalls.push_back(Inst);
530struct AddressSanitizer {
531 AddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
532 const StackSafetyGlobalInfo *SSGI,
533 int InstrumentationWithCallsThreshold,
534 uint32_t MaxInlinePoisoningSize,
bool CompileKernel =
false,
535 bool Recover =
false,
bool UseAfterScope =
false,
537 AsanDetectStackUseAfterReturnMode::Runtime)
538 : Opts(Opts),
M(
M), Inserter(
M),
539 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
540 Recover(
valueOr(Opts.asan_recover, Recover)),
541 UseAfterScope(UseAfterScope || Opts.asan_use_after_scope),
542 UseAfterReturn(Opts.asan_use_after_return.value_or(UseAfterReturn)),
543 SSGI(SSGI), InstrumentationWithCallsThreshold(
544 Opts.asan_instrumentation_with_call_threshold.value_or(
545 InstrumentationWithCallsThreshold)),
546 MaxInlinePoisoningSize(Opts.asan_max_inline_poisoning_size.value_or(
547 MaxInlinePoisoningSize)) {
548 C = &(
M.getContext());
549 DL = &
M.getDataLayout();
550 LongSize =
M.getDataLayout().getPointerSizeInBits();
551 IntptrTy = Type::getIntNTy(*
C, LongSize);
552 PtrTy = PointerType::getUnqual(*
C);
553 Int32Ty = Type::getInt32Ty(*
C);
554 TargetTriple =
M.getTargetTriple();
559 assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
567 bool isInterestingAlloca(
const AllocaInst &AI);
569 bool ignoreAccess(Instruction *Inst,
Value *Ptr);
571 Instruction *
I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
572 const TargetTransformInfo *
TTI);
574 void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
575 InterestingMemoryOperand &O,
bool UseCalls,
576 const DataLayout &
DL, RuntimeCallInserter &RTCI);
577 bool instrumentPointerComparisonOrSubtraction(Instruction *
I,
578 RuntimeCallInserter &RTCI);
580 Value *Addr, MaybeAlign Alignment,
581 uint32_t TypeStoreSize,
bool IsWrite,
582 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
583 RuntimeCallInserter &RTCI);
584 Instruction *instrumentAMDGPUAddress(Instruction *OrigIns,
585 Instruction *InsertBefore,
Value *Addr,
586 uint32_t TypeStoreSize,
bool IsWrite,
587 Value *SizeArgument);
590 void instrumentUnusualSizeOrAlignment(Instruction *
I,
591 Instruction *InsertBefore,
Value *Addr,
592 TypeSize TypeStoreSize,
bool IsWrite,
593 Value *SizeArgument,
bool UseCalls,
595 RuntimeCallInserter &RTCI);
596 void instrumentMaskedLoadOrStore(AddressSanitizer *
Pass,
const DataLayout &
DL,
599 MaybeAlign Alignment,
unsigned Granularity,
600 Type *OpType,
bool IsWrite,
601 Value *SizeArgument,
bool UseCalls,
602 uint32_t Exp, RuntimeCallInserter &RTCI);
604 Value *ShadowValue, uint32_t TypeStoreSize);
606 bool IsWrite,
size_t AccessSizeIndex,
607 Value *SizeArgument, uint32_t Exp,
608 RuntimeCallInserter &RTCI);
609 void instrumentMemIntrinsic(MemIntrinsic *
MI, RuntimeCallInserter &RTCI);
611 bool suppressInstrumentationSiteForDebug(
int &Instrumented);
612 bool instrumentFunction(
Function &
F,
const TargetLibraryInfo *TLI,
613 const TargetTransformInfo *
TTI);
614 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
615 bool maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
616 void markEscapedLocalAllocas(
Function &
F);
617 void markCatchParametersAsUninteresting(
Function &
F);
620 friend struct FunctionStackPoisoner;
622 void initializeCallbacks(
const TargetLibraryInfo *TLI);
624 bool LooksLikeCodeInBug11395(Instruction *
I);
625 bool GlobalIsLinkerInitialized(GlobalVariable *
G);
626 bool isSafeAccess(ObjectSizeOffsetVisitor &ObjSizeVis,
Value *Addr,
627 TypeSize TypeStoreSize)
const;
630 struct FunctionStateRAII {
631 AddressSanitizer *
Pass;
633 FunctionStateRAII(AddressSanitizer *
Pass) :
Pass(
Pass) {
635 "last pass forgot to clear cache");
639 ~FunctionStateRAII() {
640 Pass->LocalDynamicShadow =
nullptr;
641 Pass->ProcessedAllocas.clear();
645 const InstrumentationOptions &Opts;
647 AsanFunctionInserter Inserter;
649 const DataLayout *
DL;
659 ShadowMapping Mapping;
660 FunctionCallee AsanHandleNoReturnFunc;
661 FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction;
669 FunctionCallee AsanErrorCallbackSized[2][2];
670 FunctionCallee AsanMemoryAccessCallbackSized[2][2];
671 FunctionCallee AsanAssumeDereferenceableCallback;
673 FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
674 Value *LocalDynamicShadow =
nullptr;
675 const StackSafetyGlobalInfo *SSGI;
676 DenseMap<const AllocaInst *, bool> ProcessedAllocas;
678 FunctionCallee AMDGPUAddressShared;
679 FunctionCallee AMDGPUAddressPrivate;
680 int InstrumentationWithCallsThreshold;
681 uint32_t MaxInlinePoisoningSize;
684class ModuleAddressSanitizer {
686 ModuleAddressSanitizer(
const InstrumentationOptions &Opts,
Module &M,
687 bool InsertVersionCheck,
bool CompileKernel =
false,
688 bool Recover =
false,
bool UseGlobalsGC =
true,
689 bool UseOdrIndicator =
true,
692 : Opts(Opts),
M(
M), Inserter(
M),
693 CompileKernel(
valueOr(Opts.asan_kernel, CompileKernel)),
694 InsertVersionCheck(
valueOr(Opts.asan_guard_against_version_mismatch,
695 InsertVersionCheck)),
696 Recover(
valueOr(Opts.asan_recover, Recover)),
697 UseGlobalsGC(UseGlobalsGC && Opts.asan_globals_live_support &&
698 !this->CompileKernel),
700 UsePrivateAlias(
valueOr(Opts.asan_use_private_alias, UseOdrIndicator)),
701 UseOdrIndicator(
valueOr(Opts.asan_use_odr_indicator, UseOdrIndicator)),
710 UseCtorComdat(UseGlobalsGC && Opts.asan_with_comdat &&
711 !this->CompileKernel),
712 DestructorKind(Opts.asan_destructor_kind.value_or(DestructorKind)),
713 ConstructorKind(Opts.asan_constructor_kind.value_or(ConstructorKind)) {
714 C = &(
M.getContext());
715 int LongSize =
M.getDataLayout().getPointerSizeInBits();
716 IntptrTy = Type::getIntNTy(*
C, LongSize);
717 PtrTy = PointerType::getUnqual(*
C);
718 TargetTriple =
M.getTargetTriple();
722 assert(this->DestructorKind != AsanDtorKind::Invalid);
725 bool instrumentModule();
728 void initializeCallbacks();
730 void instrumentGlobals(
IRBuilder<> &IRB,
bool *CtorComdat);
737 const std::string &UniqueModuleId);
742 InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB,
746 GlobalVariable *CreateMetadataGlobal(Constant *Initializer,
747 StringRef OriginalName);
748 void SetComdatForGlobalMetadata(GlobalVariable *
G, GlobalVariable *
Metadata,
749 StringRef InternalSuffix);
752 const GlobalVariable *getExcludedAliasedGlobal(
const GlobalAlias &GA)
const;
753 bool shouldInstrumentGlobal(GlobalVariable *
G)
const;
754 bool ShouldUseMachOGlobalsSection()
const;
755 StringRef getGlobalMetadataSection()
const;
756 void poisonOneInitializer(
Function &GlobalInit);
757 void createInitializerPoisonCalls();
758 uint64_t getMinRedzoneSizeForGlobal()
const {
762 int GetAsanVersion()
const;
763 GlobalVariable *getOrCreateModuleName();
765 const InstrumentationOptions &Opts;
767 AsanFunctionInserter Inserter;
769 bool InsertVersionCheck;
772 bool UsePrivateAlias;
773 bool UseOdrIndicator;
781 ShadowMapping Mapping;
782 FunctionCallee AsanPoisonGlobals;
783 FunctionCallee AsanUnpoisonGlobals;
784 FunctionCallee AsanRegisterGlobals;
785 FunctionCallee AsanUnregisterGlobals;
786 FunctionCallee AsanRegisterImageGlobals;
787 FunctionCallee AsanUnregisterImageGlobals;
788 FunctionCallee AsanRegisterElfGlobals;
789 FunctionCallee AsanUnregisterElfGlobals;
791 Function *AsanCtorFunction =
nullptr;
792 Function *AsanDtorFunction =
nullptr;
793 GlobalVariable *ModuleName =
nullptr;
805struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
806 const InstrumentationOptions &Opts;
808 AddressSanitizer &ASan;
809 RuntimeCallInserter &RTCI;
814 ShadowMapping Mapping;
818 SmallVector<Instruction *, 8> RetVec;
822 FunctionCallee AsanSetShadowFunc[0x100] = {};
823 FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc;
824 FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc;
827 struct AllocaPoisonCall {
828 IntrinsicInst *InsBefore;
838 AllocaInst *DynamicAllocaLayout =
nullptr;
839 IntrinsicInst *LocalEscapeCall =
nullptr;
841 bool HasInlineAsm =
false;
842 bool HasReturnsTwiceCall =
false;
845 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan,
846 RuntimeCallInserter &RTCI)
847 : Opts(ASan.Opts),
F(
F), ASan(ASan), RTCI(RTCI),
849 IntptrTy(ASan.IntptrTy),
851 Mapping(ASan.Mapping),
852 PoisonStack(Opts.asan_stack &&
853 !
F.
getParent()->getTargetTriple().isAMDGPU()) {}
859 if (Opts.asan_redzone_byval_args)
860 copyArgsPassedByValToAllocas();
865 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
867 initializeCallbacks(*
F.getParent());
869 processDynamicAllocas();
870 processStaticAllocas();
872 if (Opts.asan_debug_stack) {
881 void copyArgsPassedByValToAllocas();
886 void processStaticAllocas();
887 void processDynamicAllocas();
889 void createDynamicAllocasInitStorage();
894 void visitReturnInst(ReturnInst &RI) {
895 if (CallInst *CI = RI.
getParent()->getTerminatingMustTailCall())
902 void visitResumeInst(ResumeInst &RI) { RetVec.
push_back(&RI); }
905 void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.
push_back(&CRI); }
907 void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
917 Intrinsic::get_dynamic_area_offset, {IntptrTy}, {});
923 RTCI.createRuntimeCall(
924 IRB, AsanAllocasUnpoisonFunc,
925 {IRB.
CreateLoad(IntptrTy, DynamicAllocaLayout), DynamicAreaPtr});
929 void unpoisonDynamicAllocas() {
930 for (Instruction *Ret : RetVec)
931 unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout);
933 for (Instruction *StackRestoreInst : StackRestoreVec)
934 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
935 StackRestoreInst->getOperand(0));
948 void handleDynamicAllocaCall(AllocaInst *AI);
951 void visitAllocaInst(AllocaInst &AI) {
953 if (!ASan.isInterestingAlloca(AI) || AI.
isScalable()) {
957 if (AllocaVec.
empty())
973 void visitIntrinsicInst(IntrinsicInst &
II) {
975 if (ID == Intrinsic::stackrestore) StackRestoreVec.
push_back(&
II);
976 if (ID == Intrinsic::localescape) LocalEscapeCall = &
II;
977 if (!ASan.UseAfterScope)
979 if (!
II.isLifetimeStartOrEnd())
984 if (!AI || !ASan.isInterestingAlloca(*AI))
994 bool DoPoison = (
ID == Intrinsic::lifetime_end);
995 AllocaPoisonCall APC = {&
II, AI, *
Size, DoPoison};
997 StaticAllocaPoisonCallVec.
push_back(APC);
998 else if (Opts.asan_instrument_dynamic_allocas)
999 DynamicAllocaPoisonCallVec.
push_back(APC);
1002 void visitCallBase(CallBase &CB) {
1004 HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
1005 HasReturnsTwiceCall |= CI->canReturnTwice();
1010 void initializeCallbacks(
Module &M);
1015 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1017 void copyToShadow(ArrayRef<uint8_t> ShadowMask, ArrayRef<uint8_t> ShadowBytes,
1020 void copyToShadowInline(ArrayRef<uint8_t> ShadowMask,
1021 ArrayRef<uint8_t> ShadowBytes,
size_t Begin,
1026 Value *createAllocaForLayout(
IRBuilder<> &IRB,
const ASanStackFrameLayout &L,
1029 Instruction *ThenTerm,
Value *ValueIfFalse);
1036 static_cast<PassInfoMixin<AddressSanitizerPass> *
>(
this)->
printPipeline(
1037 OS, MapClassName2PassName);
1039 if (Options.CompileKernel)
1041 if (Options.UseAfterScope)
1042 OS <<
"use-after-scope";
1050 : Options(Options), UseGlobalGC(UseGlobalGC),
1051 UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1052 ConstructorKind(ConstructorKind) {}
1062 ModuleAddressSanitizer ModuleSanitizer(Opts, M, Options.InsertVersionCheck,
1063 Options.CompileKernel, Options.Recover,
1064 UseGlobalGC, UseOdrIndicator,
1065 DestructorKind, ConstructorKind);
1076 if (!Opts.asan_debug_func.empty() && Opts.asan_debug_func ==
F.getName())
1078 if (
F.getName().starts_with(
"__asan_"))
1080 if (
F.isPresplitCoroutine())
1082 AddressSanitizer FunctionSanitizer(
1083 Opts, M, SSGI, Options.InstrumentationWithCallsThreshold,
1084 Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
1085 Options.UseAfterScope, Options.UseAfterReturn);
1088 Modified |= FunctionSanitizer.instrumentFunction(
F, &TLI, &
TTI);
1090 Modified |= ModuleSanitizer.instrumentModule();
1111 if (
G->getName().starts_with(
"llvm.") ||
1113 G->getName().starts_with(
"__llvm_gcov_ctr") ||
1115 G->getName().starts_with(
"__llvm_rtti_proxy"))
1131 if (AddrSpace == 3 || AddrSpace == 5)
1141 if (!Opts.asan_instrument_address_spaces.empty())
1142 return is_contained(Opts.asan_instrument_address_spaces, AddrSpace);
1147 return AddrSpace == 0;
1151 if (TargetTriple.isOSDarwin() &&
1155 ConstantInt::get(IntptrTy, ~(
uint64_t(0x0f) << 56)));
1158 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1159 if (Mapping.Offset == 0)
return Shadow;
1162 if (LocalDynamicShadow)
1163 ShadowBase = LocalDynamicShadow;
1165 ShadowBase = ConstantInt::get(IntptrTy, Mapping.Offset);
1166 if (Mapping.OrShadowOffset)
1167 return IRB.
CreateOr(Shadow, ShadowBase);
1169 return IRB.
CreateAdd(Shadow, ShadowBase);
1174 RuntimeCallInserter &RTCI) {
1177 RTCI.createRuntimeCall(
1183 RTCI.createRuntimeCall(
1189 MI->eraseFromParent();
1193bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1194 auto [It,
Inserted] = ProcessedAllocas.try_emplace(&AI);
1197 return It->getSecond();
1199 bool IsInteresting =
1210 !(SSGI && SSGI->
isSafe(AI)));
1212 It->second = IsInteresting;
1213 return IsInteresting;
1233 if (Opts.asan_skip_promotable_allocas && !isInterestingAlloca(*AI))
1243void AddressSanitizer::getInterestingMemoryOperands(
1247 if (LocalDynamicShadow ==
I)
1251 if (!Opts.asan_instrument_reads || ignoreAccess(
I, LI->getPointerOperand()))
1253 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
1254 LI->getType(), LI->getAlign());
1256 if (!Opts.asan_instrument_writes ||
1257 ignoreAccess(
I,
SI->getPointerOperand()))
1260 SI->getValueOperand()->getType(),
SI->getAlign());
1262 if (!Opts.asan_instrument_atomics ||
1263 ignoreAccess(
I, RMW->getPointerOperand()))
1265 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
1266 RMW->getValOperand()->getType(), std::nullopt);
1268 if (!Opts.asan_instrument_atomics ||
1269 ignoreAccess(
I, XCHG->getPointerOperand()))
1271 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
1272 XCHG->getCompareOperand()->getType(),
1275 switch (CI->getIntrinsicID()) {
1276 case Intrinsic::masked_load:
1277 case Intrinsic::masked_store:
1278 case Intrinsic::masked_gather:
1279 case Intrinsic::masked_scatter: {
1280 bool IsWrite = CI->getType()->isVoidTy();
1282 unsigned OpOffset = IsWrite ? 1 : 0;
1283 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1286 auto BasePtr = CI->getOperand(OpOffset);
1287 if (ignoreAccess(
I, BasePtr))
1289 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1291 Value *
Mask = CI->getOperand(1 + OpOffset);
1292 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, Mask);
1295 case Intrinsic::masked_expandload:
1296 case Intrinsic::masked_compressstore: {
1297 bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_compressstore;
1298 unsigned OpOffset = IsWrite ? 1 : 0;
1299 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1301 auto BasePtr = CI->getOperand(OpOffset);
1302 if (ignoreAccess(
I, BasePtr))
1305 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1308 Value *
Mask = CI->getOperand(1 + OpOffset);
1311 Value *ExtMask =
IB.CreateZExt(Mask, ExtTy);
1312 Value *EVL =
IB.CreateAddReduce(ExtMask);
1313 Value *TrueMask = ConstantInt::get(
Mask->getType(), 1);
1314 Interesting.
emplace_back(
I, OpOffset, IsWrite, Ty, Alignment, TrueMask,
1318 case Intrinsic::vp_load:
1319 case Intrinsic::vp_store:
1320 case Intrinsic::experimental_vp_strided_load:
1321 case Intrinsic::experimental_vp_strided_store: {
1323 unsigned IID = CI->getIntrinsicID();
1324 bool IsWrite = CI->getType()->isVoidTy();
1325 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1327 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1328 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1330 Value *Stride =
nullptr;
1331 if (IID == Intrinsic::experimental_vp_strided_store ||
1332 IID == Intrinsic::experimental_vp_strided_load) {
1333 Stride = VPI->getOperand(PtrOpNo + 1);
1337 unsigned PointerAlign =
Alignment.valueOrOne().value();
1342 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1343 VPI->getMaskParam(), VPI->getVectorLengthParam(),
1347 case Intrinsic::vp_gather:
1348 case Intrinsic::vp_scatter: {
1350 unsigned IID = CI->getIntrinsicID();
1351 bool IsWrite = IID == Intrinsic::vp_scatter;
1352 if (IsWrite ? !Opts.asan_instrument_writes : !Opts.asan_instrument_reads)
1354 unsigned PtrOpNo = *VPI->getMemoryPointerParamPos(IID);
1355 Type *Ty = IsWrite ? CI->getArgOperand(0)->getType() : CI->getType();
1357 Interesting.
emplace_back(
I, PtrOpNo, IsWrite, Ty, Alignment,
1358 VPI->getMaskParam(),
1359 VPI->getVectorLengthParam());
1365 if (
TTI->getTgtMemIntrinsic(
II, IntrInfo))
1369 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
1370 if (!Opts.asan_instrument_byval || !CI->isByValArgument(ArgNo) ||
1371 ignoreAccess(
I, CI->getArgOperand(ArgNo)))
1373 Type *Ty = CI->getParamByValType(ArgNo);
1389 if (!Cmp->isRelational())
1403 if (BO->getOpcode() != Instruction::Sub)
1416 if (!
G->hasInitializer())
1419 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().IsDynInit)
1426 Type *Ty = V->getType();
1427 if (Ty->isPtrOrPtrVectorTy())
1433bool AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1435 Value *
Param[2] = {
I->getOperand(0),
I->getOperand(1)};
1450 "invalid vector pointer pair instrumentation operands");
1451 for (
unsigned Index = 0, NumElements = VTy->getNumElements();
1452 Index != NumElements; ++Index) {
1453 Value *ScalarParam[2] = {
1460 RTCI.createRuntimeCall(IRB,
F, ScalarParam);
1467 RTCI.createRuntimeCall(IRB,
F, Param);
1474 TypeSize TypeStoreSize,
bool IsWrite,
1475 Value *SizeArgument,
bool UseCalls,
1476 uint32_t Exp, RuntimeCallInserter &RTCI) {
1481 switch (FixedSize) {
1487 if (!Alignment || *Alignment >= Granularity ||
1488 *Alignment >= FixedSize / 8)
1489 return Pass->instrumentAddress(
I, InsertBefore, Addr, Alignment,
1490 FixedSize, IsWrite,
nullptr, UseCalls,
1494 Pass->instrumentUnusualSizeOrAlignment(
I, InsertBefore, Addr, TypeStoreSize,
1495 IsWrite,
nullptr, UseCalls, Exp, RTCI);
1498void AddressSanitizer::instrumentMaskedLoadOrStore(
1501 MaybeAlign Alignment,
unsigned Granularity,
Type *OpType,
bool IsWrite,
1502 Value *SizeArgument,
bool UseCalls, uint32_t Exp,
1503 RuntimeCallInserter &RTCI) {
1505 TypeSize ElemTypeSize =
DL.getTypeStoreSizeInBits(VTy->getScalarType());
1506 auto Zero = ConstantInt::get(IntptrTy, 0);
1514 Value *IsEVLZero =
IB.CreateICmpNE(EVL, ConstantInt::get(EVLType, 0));
1516 IB.SetInsertPoint(LoopInsertBefore);
1518 EVL =
IB.CreateZExtOrTrunc(EVL, IntptrTy);
1521 Value *
EC =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1522 EVL =
IB.CreateBinaryIntrinsic(Intrinsic::umin, EVL, EC);
1524 EVL =
IB.CreateElementCount(IntptrTy, VTy->getElementCount());
1529 Stride =
IB.CreateZExtOrTrunc(Stride, IntptrTy);
1533 Value *MaskElem = IRB.CreateExtractElement(Mask, Index);
1534 if (auto *MaskElemC = dyn_cast<ConstantInt>(MaskElem)) {
1535 if (MaskElemC->isZero())
1541 Instruction *ThenTerm = SplitBlockAndInsertIfThen(
1542 MaskElem, &*IRB.GetInsertPoint(), false);
1543 IRB.SetInsertPoint(ThenTerm);
1546 Value *InstrumentedAddress;
1549 cast<VectorType>(Addr->getType())->getElementType()->isPointerTy() &&
1550 "Expected vector of pointer.");
1551 InstrumentedAddress = IRB.CreateExtractElement(Addr, Index);
1552 }
else if (Stride) {
1559 Alignment, Granularity, ElemTypeSize, IsWrite,
1560 SizeArgument, UseCalls, Exp, RTCI);
1567 RuntimeCallInserter &RTCI) {
1568 Value *Addr =
O.getPtr();
1581 uint32_t
Exp = Opts.asan_force_experiment;
1583 if (Opts.asan_opt && Opts.asan_opt_globals) {
1588 (!Opts.asan_initialization_order || GlobalIsLinkerInitialized(
G)) &&
1589 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1590 NumOptimizedAccessesToGlobalVar++;
1595 if (Opts.asan_opt && Opts.asan_opt_stack) {
1598 isSafeAccess(ObjSizeVis, Addr,
O.TypeStoreSize)) {
1599 NumOptimizedAccessesToStackVar++;
1605 NumInstrumentedWrites++;
1607 NumInstrumentedReads++;
1609 if (
O.MaybeByteOffset) {
1614 if (TargetTriple.isRISCV()) {
1619 static_cast<unsigned>(LongSize)) {
1628 unsigned Granularity = 1 << Mapping.Scale;
1630 instrumentMaskedLoadOrStore(
this,
DL, IntptrTy,
O.MaybeMask,
O.MaybeEVL,
1631 O.MaybeStride,
O.getInsn(), Addr,
O.Alignment,
1632 Granularity,
O.OpType,
O.IsWrite,
nullptr,
1633 UseCalls, Exp, RTCI);
1636 Granularity,
O.TypeStoreSize,
O.IsWrite,
nullptr,
1637 UseCalls, Exp, RTCI);
1642 Value *Addr,
bool IsWrite,
1643 size_t AccessSizeIndex,
1644 Value *SizeArgument,
1646 RuntimeCallInserter &RTCI) {
1652 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][0],
1653 {Addr, SizeArgument});
1655 Call = RTCI.createRuntimeCall(IRB, AsanErrorCallbackSized[IsWrite][1],
1656 {Addr, SizeArgument, ExpVal});
1659 Call = RTCI.createRuntimeCall(
1660 IRB, AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1662 Call = RTCI.createRuntimeCall(
1663 IRB, AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal});
1672 uint32_t TypeStoreSize) {
1673 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1675 Value *LastAccessedByte =
1676 IRB.
CreateAnd(AddrLong, ConstantInt::get(IntptrTy, Granularity - 1));
1678 if (TypeStoreSize / 8 > 1)
1680 LastAccessedByte, ConstantInt::get(IntptrTy, TypeStoreSize / 8 - 1));
1683 IRB.
CreateIntCast(LastAccessedByte, ShadowValue->getType(),
false);
1688Instruction *AddressSanitizer::instrumentAMDGPUAddress(
1690 uint32_t TypeStoreSize,
bool IsWrite,
Value *SizeArgument) {
1697 return InsertBefore;
1702 Value *IsSharedOrPrivate = IRB.
CreateOr(IsShared, IsPrivate);
1704 Value *AddrSpaceZeroLanding =
1707 return InsertBefore;
1722 Trm->getParent()->setName(
"asan.report");
1733void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1736 uint32_t TypeStoreSize,
bool IsWrite,
1737 Value *SizeArgument,
bool UseCalls,
1739 RuntimeCallInserter &RTCI) {
1740 if (TargetTriple.isAMDGPU()) {
1741 InsertBefore = instrumentAMDGPUAddress(OrigIns, InsertBefore, Addr,
1742 TypeStoreSize, IsWrite, SizeArgument);
1750 if (UseCalls && Opts.asan_optimize_callbacks) {
1751 const ASanAccessInfo AccessInfo(IsWrite, CompileKernel, AccessSizeIndex);
1754 ConstantInt::get(Int32Ty, AccessInfo.Packed)});
1761 RTCI.createRuntimeCall(
1762 IRB, AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], AddrLong);
1764 RTCI.createRuntimeCall(
1765 IRB, AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1766 {AddrLong, ConstantInt::get(IRB.
getInt32Ty(), Exp)});
1773 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1775 std::max<uint64_t>(
Alignment.valueOrOne().value() >> Mapping.Scale, 1);
1780 size_t Granularity = 1ULL << Mapping.Scale;
1784 (Opts.asan_always_slow_path || (TypeStoreSize < 8 * Granularity));
1786 if (TargetTriple.isAMDGCN()) {
1788 auto *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1791 CrashTerm = genAMDGPUReportBlock(IRB, Cmp, Recover);
1792 }
else if (GenSlowPath) {
1799 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeStoreSize);
1814 CrashTerm, AddrLong, IsWrite, AccessSizeIndex, SizeArgument, Exp, RTCI);
1823void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1825 TypeSize TypeStoreSize,
bool IsWrite,
Value *SizeArgument,
bool UseCalls,
1826 uint32_t Exp, RuntimeCallInserter &RTCI) {
1834 RTCI.createRuntimeCall(IRB, AsanMemoryAccessCallbackSized[IsWrite][0],
1837 RTCI.createRuntimeCall(
1838 IRB, AsanMemoryAccessCallbackSized[IsWrite][1],
1852void ModuleAddressSanitizer::poisonOneInitializer(
Function &GlobalInit) {
1857 Value *ModuleNameAddr =
1865 for (
auto &BB : GlobalInit)
1877void ModuleAddressSanitizer::createInitializerPoisonCalls() {
1897 poisonOneInitializer(*
F);
1903ModuleAddressSanitizer::getExcludedAliasedGlobal(
const GlobalAlias &GA)
const {
1908 assert(CompileKernel &&
"Only expecting to be called when compiling kernel");
1920bool ModuleAddressSanitizer::shouldInstrumentGlobal(
GlobalVariable *
G)
const {
1921 Type *Ty =
G->getValueType();
1924 if (
G->hasSanitizerMetadata() &&
G->getSanitizerMetadata().NoAddress)
1926 if (!Ty->
isSized())
return false;
1927 if (!
G->hasInitializer())
return false;
1934 if (
G->isThreadLocal())
return false;
1936 if (
G->getAlign() && *
G->getAlign() > getMinRedzoneSizeForGlobal())
return false;
1942 if (!TargetTriple.isOSBinFormatCOFF()) {
1943 if (!
G->hasExactDefinition() ||
G->hasComdat())
1947 if (
G->isInterposable())
1951 if (
G->hasAvailableExternallyLinkage())
1958 switch (
C->getSelectionKind()) {
1969 if (
G->hasSection()) {
1979 if (Section ==
"llvm.metadata")
return false;
1986 if (
Section.starts_with(
".preinit_array") ||
1987 Section.starts_with(
".init_array") ||
1988 Section.starts_with(
".fini_array")) {
1994 if (TargetTriple.isOSBinFormatELF()) {
2008 if (TargetTriple.isOSBinFormatCOFF() &&
Section.contains(
'$')) {
2009 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): "
2014 if (TargetTriple.isOSBinFormatMachO()) {
2016 unsigned TAA = 0, StubSize = 0;
2019 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
2024 if (ParsedSegment ==
"__OBJC" ||
2025 (ParsedSegment ==
"__DATA" && ParsedSection.
starts_with(
"__objc_"))) {
2037 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
2050 if (CompileKernel) {
2053 if (
G->getName().starts_with(
"__"))
2063bool ModuleAddressSanitizer::ShouldUseMachOGlobalsSection()
const {
2064 if (!TargetTriple.isOSBinFormatMachO())
2067 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
2069 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
2071 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
2073 if (TargetTriple.isDriverKit())
2075 if (TargetTriple.isXROS())
2081StringRef ModuleAddressSanitizer::getGlobalMetadataSection()
const {
2082 switch (TargetTriple.getObjectFormat()) {
2092 "ModuleAddressSanitizer not implemented for object file format");
2099void ModuleAddressSanitizer::initializeCallbacks() {
2105 AsanUnpoisonGlobals =
2109 AsanRegisterGlobals = Inserter.insertFunction(
2111 AsanUnregisterGlobals = Inserter.insertFunction(
2116 AsanRegisterImageGlobals = Inserter.insertFunction(
2118 AsanUnregisterImageGlobals = Inserter.insertFunction(
2121 AsanRegisterElfGlobals =
2123 IntptrTy, IntptrTy, IntptrTy);
2124 AsanUnregisterElfGlobals =
2126 IntptrTy, IntptrTy, IntptrTy);
2131void ModuleAddressSanitizer::SetComdatForGlobalMetadata(
2136 if (!
G->hasName()) {
2140 G->setName(
genName(
"anon_global"));
2143 if (!InternalSuffix.
empty() &&
G->hasLocalLinkage()) {
2144 std::string
Name = std::string(
G->getName());
2145 Name += InternalSuffix;
2146 C =
M.getOrInsertComdat(Name);
2148 C =
M.getOrInsertComdat(
G->getName());
2154 if (TargetTriple.isOSBinFormatCOFF()) {
2156 if (
G->hasPrivateLinkage())
2169ModuleAddressSanitizer::CreateMetadataGlobal(
Constant *Initializer,
2171 auto Linkage = TargetTriple.isOSBinFormatMachO()
2177 Metadata->setSection(getGlobalMetadataSection());
2184Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor() {
2188 AsanDtorFunction->addFnAttr(Attribute::NoUnwind);
2196void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2200 auto &
DL =
M.getDataLayout();
2203 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2204 Constant *Initializer = MetadataInitializers[i];
2208 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2214 unsigned SizeOfGlobalStruct =
DL.getTypeAllocSize(Initializer->
getType());
2216 "global metadata will not be padded appropriately");
2219 SetComdatForGlobalMetadata(
G,
Metadata,
"");
2224 if (!MetadataGlobals.empty())
2228void ModuleAddressSanitizer::instrumentGlobalsELF(
2231 const std::string &UniqueModuleId) {
2238 bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId.empty();
2241 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2244 CreateMetadataGlobal(MetadataInitializers[i],
G->getName());
2246 Metadata->setMetadata(LLVMContext::MD_associated, MD);
2249 if (UseComdatForGlobalsGC)
2250 SetComdatForGlobalMetadata(
G,
Metadata, UniqueModuleId);
2255 if (!MetadataGlobals.empty())
2272 "__start_" + getGlobalMetadataSection());
2276 "__stop_" + getGlobalMetadataSection());
2290 IrbDtor.CreateCall(AsanUnregisterElfGlobals,
2297void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2308 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
2309 Constant *Initializer = MetadataInitializers[i];
2315 auto LivenessBinder =
2320 Twine(
"__asan_binder_") +
G->getName());
2321 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2322 LivenessGlobals[i] = Liveness;
2329 if (!LivenessGlobals.empty())
2351 IrbDtor.CreateCall(AsanUnregisterImageGlobals,
2356void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2360 unsigned N = ExtendedGlobals.
size();
2370 if (Mapping.Scale > 3)
2376 ConstantInt::get(IntptrTy,
N)});
2382 IrbDtor.CreateCall(AsanUnregisterGlobals,
2384 ConstantInt::get(IntptrTy,
N)});
2393void ModuleAddressSanitizer::instrumentGlobals(
IRBuilder<> &IRB,
2398 if (CompileKernel) {
2399 for (
auto &GA :
M.aliases()) {
2401 AliasedGlobalExclusions.
insert(GV);
2406 for (
auto &
G :
M.globals()) {
2407 if (!AliasedGlobalExclusions.
count(&
G) && shouldInstrumentGlobal(&
G))
2411 size_t n = GlobalsToChange.
size();
2412 auto &
DL =
M.getDataLayout();
2426 IntptrTy, IntptrTy, IntptrTy);
2430 for (
size_t i = 0; i < n; i++) {
2434 if (
G->hasSanitizerMetadata())
2435 MD =
G->getSanitizerMetadata();
2440 std::string NameForGlobal =
G->getName().str();
2445 Type *Ty =
G->getValueType();
2446 const uint64_t SizeInBytes =
DL.getTypeAllocSize(Ty);
2459 M, NewTy,
G->isConstant(),
Linkage, NewInitializer,
"",
G,
2460 G->getThreadLocalMode(),
G->getAddressSpace());
2470 if (TargetTriple.isOSBinFormatMachO() && !
G->hasSection() &&
2473 if (Seq && Seq->isCString())
2474 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2481 G->replaceAllUsesWith(NewGlobal);
2483 G->eraseFromParent();
2484 NewGlobals[i] = NewGlobal;
2489 bool CanUsePrivateAliases =
2490 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2491 TargetTriple.isOSBinFormatWasm();
2492 if (CanUsePrivateAliases && UsePrivateAlias) {
2495 InstrumentedGlobal =
2502 }
else if (UseOdrIndicator) {
2505 auto *ODRIndicatorSym =
2514 ODRIndicatorSym->setAlignment(
Align(1));
2521 ConstantInt::get(IntptrTy, SizeInBytes),
2522 ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
2525 ConstantInt::get(IntptrTy, MD.
IsDynInit),
2530 Initializers[i] = Initializer;
2536 for (
size_t i = 0; i < n; i++) {
2538 if (
G->getName().empty())
continue;
2543 if (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) {
2550 }
else if (n == 0) {
2553 *CtorComdat = TargetTriple.isOSBinFormatELF();
2555 *CtorComdat =
false;
2556 if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2557 InstrumentGlobalsCOFF(IRB, NewGlobals, Initializers);
2558 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2559 InstrumentGlobalsMachO(IRB, NewGlobals, Initializers);
2561 InstrumentGlobalsWithMetadataArray(IRB, NewGlobals, Initializers);
2566 if (Opts.asan_initialization_order)
2567 createInitializerPoisonCalls();
2573ModuleAddressSanitizer::getRedzoneSizeForGlobal(
uint64_t SizeInBytes)
const {
2574 constexpr uint64_t kMaxRZ = 1 << 18;
2575 const uint64_t MinRZ = getMinRedzoneSizeForGlobal();
2578 if (SizeInBytes <= MinRZ / 2) {
2582 RZ = MinRZ - SizeInBytes;
2585 RZ = std::clamp((SizeInBytes / MinRZ / 4) * MinRZ, MinRZ, kMaxRZ);
2588 if (SizeInBytes % MinRZ)
2589 RZ += MinRZ - (SizeInBytes % MinRZ);
2592 assert((RZ + SizeInBytes) % MinRZ == 0);
2597int ModuleAddressSanitizer::GetAsanVersion()
const {
2598 int LongSize =
M.getDataLayout().getPointerSizeInBits();
2599 bool isAndroid =
M.getTargetTriple().isAndroid();
2603 Version += (LongSize == 32 && isAndroid);
2618bool ModuleAddressSanitizer::instrumentModule() {
2619 initializeCallbacks();
2627 if (CompileKernel) {
2632 std::string AsanVersion = std::to_string(GetAsanVersion());
2633 std::string VersionCheckName =
2635 std::tie(AsanCtorFunction, std::ignore) =
2638 {}, VersionCheckName);
2642 bool CtorComdat =
true;
2643 if (Opts.asan_globals) {
2645 if (AsanCtorFunction) {
2646 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2647 instrumentGlobals(IRB, &CtorComdat);
2650 instrumentGlobals(IRB, &CtorComdat);
2659 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2660 if (AsanCtorFunction) {
2664 if (AsanDtorFunction) {
2669 if (AsanCtorFunction)
2671 if (AsanDtorFunction)
2681 const std::string EndingStr = Recover ?
"_noabort" :
"";
2682 AsanAssumeDereferenceableCallback =
M.getOrInsertFunction(
2683 "__asan_report_assume_dereferenceable" + EndingStr,
2688 for (
int Exp = 0;
Exp < 2;
Exp++) {
2689 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2690 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2691 const std::string ExpStr =
Exp ?
"exp_" :
"";
2692 const std::string EndingStr = Recover ?
"_noabort" :
"";
2702 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
2703 AL2 = AL2.addParamAttribute(*
C, 2, AK);
2704 AL1 = AL1.addParamAttribute(*
C, 1, AK);
2707 AsanErrorCallbackSized[AccessIsWrite][
Exp] = Inserter.insertFunction(
2711 AsanMemoryAccessCallbackSized[AccessIsWrite][
Exp] =
2712 Inserter.insertFunction(
2713 (Opts.asan_memory_access_callback_prefix + ExpStr + TypeStr +
2719 AccessSizeIndex++) {
2720 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2721 AsanErrorCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2722 Inserter.insertFunction(
2726 AsanMemoryAccessCallback[AccessIsWrite][
Exp][AccessSizeIndex] =
2727 Inserter.insertFunction(
2728 (Opts.asan_memory_access_callback_prefix + ExpStr + Suffix +
2736 const std::string MemIntrinCallbackPrefix =
2737 (CompileKernel && !Opts.asan_kernel_mem_intrinsic_prefix)
2739 : Opts.asan_memory_access_callback_prefix.str();
2740 AsanMemmove = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memmove",
2741 PtrTy, PtrTy, PtrTy, IntptrTy);
2742 AsanMemcpy = Inserter.insertFunction(MemIntrinCallbackPrefix +
"memcpy",
2743 PtrTy, PtrTy, PtrTy, IntptrTy);
2745 Inserter.insertFunction(MemIntrinCallbackPrefix +
"memset",
2750 AsanHandleNoReturnFunc =
2753 AsanPtrCmpFunction =
2755 AsanPtrSubFunction =
2757 if (Mapping.InGlobal)
2758 AsanShadowGlobal =
M.getOrInsertGlobal(
"__asan_shadow",
2761 AMDGPUAddressShared =
2767bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2775 if (
F.getName().contains(
" load]")) {
2785bool AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &
F) {
2791 if (Mapping.InGlobal) {
2792 if (Opts.asan_with_ifunc_suppress_remat) {
2799 LocalDynamicShadow =
2800 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
2802 LocalDynamicShadow =
2806 Value *GlobalDynamicAddress =
F.getParent()->getOrInsertGlobal(
2808 LocalDynamicShadow = IRB.
CreateLoad(IntptrTy, GlobalDynamicAddress);
2813void AddressSanitizer::markEscapedLocalAllocas(
Function &
F) {
2818 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
2822 if (!
F.getParent()->getFunction(
"llvm.localescape"))
return;
2828 if (
II &&
II->getIntrinsicID() == Intrinsic::localescape) {
2830 for (
Value *Arg :
II->args()) {
2833 "non-static alloca arg to localescape");
2834 ProcessedAllocas[AI] =
false;
2843void AddressSanitizer::markCatchParametersAsUninteresting(
Function &
F) {
2849 for (
Value *Operand : CatchPad->arg_operands())
2851 ProcessedAllocas[AI] =
false;
2857bool AddressSanitizer::suppressInstrumentationSiteForDebug(
int &Instrumented) {
2858 bool ShouldInstrument = Opts.asan_debug_min < 0 || Opts.asan_debug_max < 0 ||
2859 (Instrumented >= Opts.asan_debug_min &&
2860 Instrumented <= Opts.asan_debug_max);
2862 return !ShouldInstrument;
2865bool AddressSanitizer::instrumentFunction(
Function &
F,
2868 bool FunctionModified =
false;
2871 if (
F.hasFnAttribute(Attribute::Naked))
2872 return FunctionModified;
2877 if (maybeInsertAsanInitAtFunctionEntry(
F))
2878 FunctionModified =
true;
2881 if (!
F.hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
2883 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2884 return FunctionModified;
2888 initializeCallbacks(TLI);
2890 FunctionStateRAII CleanupObj(
this);
2892 RuntimeCallInserter RTCI(
F);
2894 FunctionModified |= maybeInsertDynamicShadowAtFunctionEntry(
F);
2898 markEscapedLocalAllocas(
F);
2900 if (TargetTriple.isOSWindows())
2901 markCatchParametersAsUninteresting(
F);
2914 for (
auto &BB :
F) {
2916 TempsToInstrument.
clear();
2917 int NumInsnsPerBB = 0;
2918 for (
auto &Inst : BB) {
2919 if (LooksLikeCodeInBug11395(&Inst))
return false;
2927 if (!InterestingOperands.
empty()) {
2928 for (
auto &Operand : InterestingOperands) {
2929 if (Opts.asan_opt && Opts.asan_opt_same_temp) {
2930 Value *Ptr = Operand.getPtr();
2934 if (Operand.MaybeMask) {
2935 if (TempsToInstrument.
count(Ptr))
2938 if (!TempsToInstrument.
insert(Ptr).second)
2942 OperandsToInstrument.
push_back(Operand);
2945 }
else if (((Opts.asan_detect_invalid_pointer_pair ||
2946 Opts.asan_detect_invalid_pointer_cmp) &&
2948 ((Opts.asan_detect_invalid_pointer_pair ||
2949 Opts.asan_detect_invalid_pointer_sub) &&
2951 PointerComparisonsOrSubtracts.
push_back(&Inst);
2956 }
else if (Opts.asan_instrument_assume_dereferenceable &&
2965 TempsToInstrument.
clear();
2972 if (NumInsnsPerBB >= Opts.asan_max_ins_per_bb)
2977 bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
2978 OperandsToInstrument.
size() + IntrinToInstrument.
size() >
2979 (
unsigned)InstrumentationWithCallsThreshold);
2984 int NumInstrumented = 0;
2985 for (
auto &Operand : OperandsToInstrument) {
2986 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2987 instrumentMop(ObjSizeVis, Operand, UseCalls,
2988 F.getDataLayout(), RTCI);
2989 FunctionModified =
true;
2991 for (
auto *Inst : IntrinToInstrument) {
2992 if (!suppressInstrumentationSiteForDebug(NumInstrumented))
2993 instrumentMemIntrinsic(Inst, RTCI);
2994 FunctionModified =
true;
2997 FunctionStackPoisoner FSP(
F, *
this, RTCI);
2998 bool ChangedStack = FSP.runOnFunction();
3002 for (
auto *CI : NoReturnCalls) {
3004 RTCI.createRuntimeCall(IRB, AsanHandleNoReturnFunc, {});
3007 for (
auto *Inst : PointerComparisonsOrSubtracts) {
3008 FunctionModified |= instrumentPointerComparisonOrSubtraction(Inst, RTCI);
3011 for (
auto *AI : DerefAssumptions) {
3013 Value *Ptr = Bundle->Inputs[0];
3026 RTCI.createRuntimeCall(IRB, AsanAssumeDereferenceableCallback,
3027 {AddrLong, SizeExt});
3029 FunctionModified =
true;
3033 if (ChangedStack || !NoReturnCalls.empty())
3034 FunctionModified =
true;
3036 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
3039 return FunctionModified;
3045bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *
I) {
3046 if (LongSize != 32)
return false;
3055void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
3059 const char *MallocNameTemplate =
3064 std::string Suffix =
itostr(Index);
3065 AsanStackMallocFunc[
Index] = ASan.Inserter.insertFunction(
3066 MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
3067 AsanStackFreeFunc[
Index] =
3072 if (ASan.UseAfterScope) {
3073 AsanPoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3075 AsanUnpoisonStackMemoryFunc = ASan.Inserter.insertFunction(
3079 for (
size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
3080 0xf3, 0xf5, 0xf8}) {
3081 std::ostringstream
Name;
3083 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
3084 AsanSetShadowFunc[Val] = ASan.Inserter.insertFunction(
3088 AsanAllocaPoisonFunc = ASan.Inserter.insertFunction(
3090 AsanAllocasUnpoisonFunc = ASan.Inserter.insertFunction(
3096 size_t Begin,
size_t End,
3098 Value *ShadowBase) {
3102 const size_t LargestStoreSizeInBytes =
3103 std::min<size_t>(
sizeof(
uint64_t), ASan.LongSize / 8);
3105 const bool IsLittleEndian =
F.getDataLayout().isLittleEndian();
3111 for (
size_t i = Begin; i <
End;) {
3112 if (!ShadowMask[i]) {
3118 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
3120 while (StoreSizeInBytes >
End - i)
3121 StoreSizeInBytes /= 2;
3124 for (
size_t j = StoreSizeInBytes - 1;
j && !ShadowMask[i +
j]; --
j) {
3125 while (j <= StoreSizeInBytes / 2)
3126 StoreSizeInBytes /= 2;
3130 for (
size_t j = 0;
j < StoreSizeInBytes;
j++) {
3132 Val |= (
uint64_t)ShadowBytes[i + j] << (8 * j);
3134 Val = (Val << 8) | ShadowBytes[i + j];
3137 Value *Ptr = IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i));
3143 i += StoreSizeInBytes;
3150 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
3155 size_t Begin,
size_t End,
3158 size_t Done = Begin;
3159 for (
size_t i = Begin, j = Begin + 1; i <
End; i =
j++) {
3160 if (!ShadowMask[i]) {
3164 uint8_t Val = ShadowBytes[i];
3165 if (!AsanSetShadowFunc[Val])
3169 for (;
j <
End && ShadowMask[
j] && Val == ShadowBytes[
j]; ++
j) {
3172 if (j - i >= ASan.MaxInlinePoisoningSize) {
3173 copyToShadowInline(ShadowMask, ShadowBytes,
Done, i, IRB, ShadowBase);
3174 RTCI.createRuntimeCall(
3175 IRB, AsanSetShadowFunc[Val],
3176 {IRB.
CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),
3177 ConstantInt::get(IntptrTy, j - i)});
3182 copyToShadowInline(ShadowMask, ShadowBytes,
Done,
End, IRB, ShadowBase);
3190 for (
int i = 0;; i++, MaxSize *= 2)
3191 if (LocalStackSize <= MaxSize)
return i;
3195void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
3197 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
3205 if (Arg.hasByValAttr()) {
3206 Type *Ty = Arg.getParamByValType();
3208 DL.getValueOrABITypeAlignment(Arg.getParamAlign(), Ty);
3212 (Arg.hasName() ? Arg.getName() :
"Arg" +
Twine(Arg.getArgNo())) +
3215 Arg.replaceAllUsesWith(AI);
3217 uint64_t AllocSize =
DL.getTypeAllocSize(Ty);
3218 IRB.
CreateMemCpy(AI, Alignment, &Arg, Alignment, AllocSize);
3226 Value *ValueIfFalse) {
3229 PHI->addIncoming(ValueIfFalse, CondBlock);
3231 PHI->addIncoming(ValueIfTrue, ThenBlock);
3235Value *FunctionStackPoisoner::createAllocaForLayout(
3244 nullptr,
"MyAlloca");
3247 assert((Opts.asan_realign_stack & (Opts.asan_realign_stack - 1)) == 0);
3249 std::max(
L.FrameAlignment,
uint64_t(Opts.asan_realign_stack));
3254void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
3257 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
3262void FunctionStackPoisoner::processDynamicAllocas() {
3263 if (!Opts.asan_instrument_dynamic_allocas || DynamicAllocaVec.
empty()) {
3269 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
3272 assert(ASan.isInterestingAlloca(*APC.AI));
3273 assert(!APC.AI->isStaticAlloca());
3276 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
3283 createDynamicAllocasInitStorage();
3284 for (
auto &AI : DynamicAllocaVec)
3285 handleDynamicAllocaCall(AI);
3286 unpoisonDynamicAllocas();
3298 for (
Instruction *It = Start; It; It = It->getNextNode()) {
3315 if (!Alloca || ASan.isInterestingAlloca(*Alloca))
3320 bool IsArgInitViaCast =
3325 Val == It->getPrevNode();
3326 bool IsArgInit = IsDirectArgInit || IsArgInitViaCast;
3330 if (IsArgInitViaCast)
3345 if (AI->
hasMetadata(LLVMContext::MD_annotation)) {
3348 for (
auto &Annotation : AllocaAnnotations->
operands()) {
3352 for (
unsigned Index = 0; Index < AnnotationTuple->getNumOperands();
3355 auto MetadataString =
3357 if (MetadataString->getString() ==
"alloca_name_altered")
3366void FunctionStackPoisoner::processStaticAllocas() {
3367 if (AllocaVec.
empty()) {
3372 int StackMallocIdx = -1;
3374 if (
auto SP =
F.getSubprogram())
3375 EntryDebugLocation =
3384 auto InsBeforeB = InsBefore->
getParent();
3385 assert(InsBeforeB == &
F.getEntryBlock());
3386 for (
auto *AI : StaticAllocasToMoveUp)
3397 ArgInitInst->moveBefore(InsBefore->
getIterator());
3400 if (LocalEscapeCall)
3408 ASan.getAllocaSizeInBytes(*AI),
3419 uint64_t Granularity = 1ULL << Mapping.Scale;
3420 uint64_t MinHeaderSize = std::max((
uint64_t)ASan.LongSize / 2, Granularity);
3426 for (
auto &
Desc : SVD)
3430 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3433 assert(ASan.isInterestingAlloca(*APC.AI));
3434 assert(APC.AI->isStaticAlloca());
3439 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
3440 if (LifetimeLoc->getFile() == FnLoc->getFile())
3441 if (
unsigned Line = LifetimeLoc->getLine())
3442 Desc.Line = std::min(
Desc.Line ?
Desc.Line : Line, Line);
3448 LLVM_DEBUG(
dbgs() << DescriptionString <<
" --- " <<
L.FrameSize <<
"\n");
3450 bool DoStackMalloc =
3453 bool DoDynamicAlloca = Opts.asan_stack_dynamic_alloca;
3460 DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3461 DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
3463 Type *PtrTy =
F.getDataLayout().getAllocaPtrType(
F.getContext());
3464 Value *StaticAlloca =
3465 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
3467 Value *FakeStackPtr;
3468 Value *FakeStackInt;
3469 Value *LocalStackBase;
3470 Value *LocalStackBaseAlloca;
3473 if (DoStackMalloc) {
3474 LocalStackBaseAlloca =
3475 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
3482 Constant *OptionDetectUseAfterReturn =
F.getParent()->getOrInsertGlobal(
3492 Value *FakeStackValue =
3493 RTCI.createRuntimeCall(IRBIf, AsanStackMallocFunc[StackMallocIdx],
3494 ConstantInt::get(IntptrTy, LocalStackSize));
3496 FakeStackInt = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue,
3497 Term, ConstantInt::get(IntptrTy, 0));
3505 RTCI.createRuntimeCall(IRB, AsanStackMallocFunc[StackMallocIdx],
3506 ConstantInt::get(IntptrTy, LocalStackSize));
3509 Value *NoFakeStack =
3514 Value *AllocaValue =
3515 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
3519 createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStackPtr);
3520 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3528 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3529 LocalStackBaseAlloca = LocalStackBase;
3534 for (
const auto &
Desc : SVD) {
3538 LocalStackBase, ConstantInt::get(IntptrTy,
Desc.Offset));
3551 LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize / 8));
3559 LocalStackBase, ConstantInt::get(IntptrTy, 2 * ASan.LongSize / 8));
3566 ASan.memToShadow(IRB.
CreatePtrToInt(LocalStackBase, IntptrTy), IRB);
3569 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3571 if (!StaticAllocaPoisonCallVec.empty()) {
3575 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3578 size_t Begin =
Desc.Offset /
L.Granularity;
3579 size_t End = Begin + (APC.Size +
L.Granularity - 1) /
L.Granularity;
3582 copyToShadow(ShadowAfterScope,
3583 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin,
End,
3589 for (
Value *NewAllocaPtr : NewAllocaPtrs) {
3592 if (
I->isLifetimeStartOrEnd())
3593 I->eraseFromParent();
3606 if (DoStackMalloc) {
3607 assert(StackMallocIdx >= 0);
3624 if (ASan.MaxInlinePoisoningSize != 0 && StackMallocIdx <= 4) {
3626 ShadowAfterReturn.
resize(ClassSize /
L.Granularity,
3628 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3630 Value *SavedFlagPtrPtr = IRBPoison.CreatePtrAdd(
3632 ConstantInt::get(IntptrTy, ClassSize - ASan.LongSize / 8));
3633 Value *SavedFlagPtr = IRBPoison.CreateLoad(IntptrTy, SavedFlagPtrPtr);
3634 IRBPoison.CreateStore(
3636 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getPtrTy()));
3639 RTCI.createRuntimeCall(
3640 IRBPoison, AsanStackFreeFunc[StackMallocIdx],
3641 {FakeStackInt, ConstantInt::get(IntptrTy, LocalStackSize)});
3645 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3647 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3652 for (
auto *AI : AllocaVec)
3660 Value *SizeArg = ConstantInt::get(IntptrTy,
Size);
3661 RTCI.createRuntimeCall(
3662 IRB, DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3663 {AddrArg, SizeArg});
3674void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3682 Value *AllocaRzMask = ConstantInt::get(IntptrTy, AllocaRedzoneMask);
3716 ConstantInt::get(IntptrTy,
Alignment.value()));
3719 RTCI.createRuntimeCall(IRB, AsanAllocaPoisonFunc, {NewAddress, OldSize});
3730 if (
I->isLifetimeStartOrEnd())
3731 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
SmallVector< MachineOperand, 4 > 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.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
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.