90 #define DEBUG_TYPE "asan" 137 "__asan_unregister_globals";
139 "__asan_register_image_globals";
141 "__asan_unregister_image_globals";
143 "__asan_register_elf_globals";
145 "__asan_unregister_elf_globals";
150 "__asan_version_mismatch_check_v";
162 "__asan_poison_stack_memory";
164 "__asan_unpoison_stack_memory";
169 "___asan_globals_registered";
172 "__asan_option_detect_stack_use_after_return";
175 "__asan_shadow_memory_dynamic_address";
188 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
193 cl::desc(
"Enable recovery mode (continue-after-error)."),
198 cl::desc(
"instrument read instructions"),
202 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
206 "asan-instrument-atomics",
211 "asan-always-slow-path",
216 "asan-force-dynamic-shadow",
217 cl::desc(
"Load shadow address into a local variable for each function"),
222 cl::desc(
"Access dynamic shadow through an ifunc global on " 223 "platforms that support this"),
227 "asan-with-ifunc-suppress-remat",
228 cl::desc(
"Suppress rematerialization of dynamic shadow address by passing " 229 "it through inline asm in prologue."),
237 "asan-max-ins-per-bb",
cl::init(10000),
238 cl::desc(
"maximal number of instructions to instrument in any given BB"),
245 "asan-max-inline-poisoning-size",
247 "Inline shadow poisoning for blocks up to the given size in bytes."),
251 cl::desc(
"Check stack-use-after-return"),
255 cl::desc(
"Create redzones for byval " 256 "arguments (extra copy " 261 cl::desc(
"Check stack-use-after-scope"),
270 cl::desc(
"Handle C++ initializer order"),
274 "asan-detect-invalid-pointer-pair",
279 "asan-realign-stack",
280 cl::desc(
"Realign stack to the value of this flag (power of two)"),
284 "asan-instrumentation-with-call-threshold",
286 "If the function being instrumented contains more than " 287 "this number of memory accesses, use callbacks instead of " 288 "inline checks (-1 means never use callbacks)."),
292 "asan-memory-access-callback-prefix",
298 cl::desc(
"instrument dynamic allocas"),
302 "asan-skip-promotable-allocas",
311 cl::desc(
"scale of asan shadow mapping"),
315 "asan-mapping-offset",
326 "asan-opt-same-temp",
cl::desc(
"Instrument the same temp just once"),
330 cl::desc(
"Don't instrument scalar globals"),
334 "asan-opt-stack",
cl::desc(
"Don't instrument scalar stack variables"),
338 "asan-stack-dynamic-alloca",
343 "asan-force-experiment",
349 cl::desc(
"Use private aliases for global variables"),
354 cl::desc(
"Use odr indicators to improve ODR reporting"),
359 cl::desc(
"Use linker features to support dead " 360 "code stripping of globals"),
367 cl::desc(
"Place ASan constructors in comdat sections"),
387 STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
388 STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
389 STATISTIC(NumOptimizedAccessesToGlobalVar,
390 "Number of optimized accesses to global vars");
391 STATISTIC(NumOptimizedAccessesToStackVar,
392 "Number of optimized accesses to stack vars");
397 struct LocationMetadata {
402 LocationMetadata() =
default;
404 bool empty()
const {
return Filename.
empty(); }
409 Filename = DIFilename->getString();
411 mdconst::extract<ConstantInt>(MDN->
getOperand(1))->getLimitedValue();
413 mdconst::extract<ConstantInt>(MDN->
getOperand(2))->getLimitedValue();
418 class GlobalsMetadata {
421 LocationMetadata SourceLoc;
423 bool IsDynInit =
false;
424 bool IsBlacklisted =
false;
429 GlobalsMetadata() =
default;
440 if (!Globals)
return;
441 for (
auto MDN : Globals->
operands()) {
444 auto *V = mdconst::extract_or_null<Constant>(MDN->
getOperand(0));
447 auto *StrippedV = V->stripPointerCasts();
452 Entry &
E = Entries[GV];
453 if (
auto *Loc = cast_or_null<MDNode>(MDN->
getOperand(1)))
454 E.SourceLoc.parse(Loc);
456 E.Name =
Name->getString();
458 mdconst::extract<ConstantInt>(MDN->
getOperand(3));
459 E.IsDynInit |= IsDynInit->
isOne();
461 mdconst::extract<ConstantInt>(MDN->
getOperand(4));
462 E.IsBlacklisted |= IsBlacklisted->
isOne();
468 auto Pos = Entries.find(
G);
469 return (Pos != Entries.end()) ? Pos->second : Entry();
473 bool inited_ =
false;
482 struct ShadowMapping {
493 bool IsAndroid = TargetTriple.
isAndroid();
497 bool IsPS4CPU = TargetTriple.
isPS4CPU();
504 bool IsMIPS32 = TargetTriple.
isMIPS32();
505 bool IsMIPS64 = TargetTriple.
isMIPS64();
506 bool IsArmOrThumb = TargetTriple.
isARM() || TargetTriple.
isThumb();
512 ShadowMapping Mapping;
519 if (LongSize == 32) {
549 else if (IsFreeBSD && !IsMIPS64)
558 else if (IsLinux && IsX86_64) {
564 }
else if (IsWindows && IsX86_64) {
592 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS4CPU &&
593 !(Mapping.Offset & (Mapping.Offset - 1)) &&
595 bool IsAndroidWithIfuncSupport =
597 Mapping.InGlobal =
ClWithIfunc && IsAndroidWithIfuncSupport && IsArmOrThumb;
605 return std::max(32U, 1U << MappingScale);
615 explicit AddressSanitizer(
bool CompileKernel =
false,
bool Recover =
false,
616 bool UseAfterScope =
false)
619 this->CompileKernel =
ClEnableKasan.getNumOccurrences() > 0 ?
625 return "AddressSanitizerFunctionPass";
634 uint64_t ArraySize = 1;
637 assert(CI &&
"non-constant array size");
641 uint64_t SizeInBytes =
643 return SizeInBytes * ArraySize;
647 bool isInterestingAlloca(
const AllocaInst &AI);
654 uint64_t *TypeSize,
unsigned *Alignment,
655 Value **MaybeMask =
nullptr);
659 void instrumentPointerComparisonOrSubtraction(
Instruction *I);
663 void instrumentUnusualSizeOrAlignment(
Instruction *I,
666 Value *SizeArgument,
bool UseCalls,
671 bool IsWrite,
size_t AccessSizeIndex,
676 bool maybeInsertAsanInitAtFunctionEntry(
Function &F);
677 void maybeInsertDynamicShadowAtFunctionEntry(
Function &F);
678 void markEscapedLocalAllocas(
Function &F);
679 bool doInitialization(
Module &M)
override;
680 bool doFinalization(
Module &M)
override;
685 friend struct FunctionStackPoisoner;
687 void initializeCallbacks(
Module &M);
692 uint64_t TypeSize)
const;
695 struct FunctionStateRAII {
696 AddressSanitizer *
Pass;
698 FunctionStateRAII(AddressSanitizer *Pass) :
Pass(Pass) {
699 assert(Pass->ProcessedAllocas.empty() &&
700 "last pass forgot to clear cache");
701 assert(!Pass->LocalDynamicShadow);
704 ~FunctionStateRAII() {
705 Pass->LocalDynamicShadow =
nullptr;
706 Pass->ProcessedAllocas.clear();
717 ShadowMapping Mapping;
720 Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
728 Function *AsanErrorCallbackSized[2][2];
729 Function *AsanMemoryAccessCallbackSized[2][2];
731 Function *AsanMemmove, *AsanMemcpy, *AsanMemset;
733 Value *LocalDynamicShadow =
nullptr;
734 GlobalsMetadata GlobalsMD;
738 class AddressSanitizerModule :
public ModulePass {
743 explicit AddressSanitizerModule(
bool CompileKernel =
false,
744 bool Recover =
false,
745 bool UseGlobalsGC =
true,
746 bool UseOdrIndicator =
false)
760 this->CompileKernel =
764 bool runOnModule(
Module &M)
override;
765 StringRef getPassName()
const override {
return "AddressSanitizerModule"; }
768 void initializeCallbacks(
Module &M);
777 const std::string &UniqueModuleId);
793 bool ShouldUseMachOGlobalsSection()
const;
794 StringRef getGlobalMetadataSection()
const;
797 size_t MinRedzoneSizeForGlobal()
const {
800 int GetAsanVersion(
const Module &M)
const;
802 GlobalsMetadata GlobalsMD;
806 bool UsePrivateAlias;
807 bool UseOdrIndicator;
812 ShadowMapping Mapping;
818 Function *AsanUnregisterImageGlobals;
822 Function *AsanCtorFunction =
nullptr;
823 Function *AsanDtorFunction =
nullptr;
835 struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
837 AddressSanitizer &ASan;
842 ShadowMapping Mapping;
847 unsigned StackAlignment;
851 Function *AsanSetShadowFunc[0x100] = {};
852 Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc;
853 Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc;
856 struct AllocaPoisonCall {
872 AllocaForValueMapTy AllocaForValue;
874 bool HasNonEmptyInlineAsm =
false;
875 bool HasReturnsTwiceCall =
false;
876 std::unique_ptr<CallInst> EmptyInlineAsm;
878 FunctionStackPoisoner(
Function &F, AddressSanitizer &ASan)
883 IntptrTy(ASan.IntptrTy),
885 Mapping(ASan.Mapping),
886 StackAlignment(1 << Mapping.Scale),
893 copyArgsPassedByValToAllocas();
898 if (AllocaVec.
empty() && DynamicAllocaVec.
empty())
return false;
902 processDynamicAllocas();
903 processStaticAllocas();
914 void copyArgsPassedByValToAllocas();
919 void processStaticAllocas();
920 void processDynamicAllocas();
922 void createDynamicAllocasInitStorage();
934 void unpoisonDynamicAllocasBeforeInst(
Instruction *InstBefore,
942 if (!isa<ReturnInst>(InstBefore)) {
954 {IRB.
CreateLoad(DynamicAllocaLayout), DynamicAreaPtr});
958 void unpoisonDynamicAllocas() {
959 for (
auto &
Ret : RetVec)
960 unpoisonDynamicAllocasBeforeInst(
Ret, DynamicAllocaLayout);
962 for (
auto &StackRestoreInst : StackRestoreVec)
963 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
964 StackRestoreInst->getOperand(0));
981 if (!ASan.isInterestingAlloca(AI)) {
985 if (AllocaVec.
empty())
1006 if (!ASan.UseAfterScope)
1017 if (SizeValue == ~0ULL ||
1022 if (!AI || !ASan.isInterestingAlloca(*AI))
1025 AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison};
1027 StaticAllocaPoisonCallVec.
push_back(APC);
1029 DynamicAllocaPoisonCallVec.
push_back(APC);
1034 if (
CallInst *CI = dyn_cast<CallInst>(I)) {
1035 HasNonEmptyInlineAsm |= CI->isInlineAsm() &&
1036 !CI->isIdenticalTo(EmptyInlineAsm.get()) &&
1037 I != ASan.LocalDynamicShadow;
1038 HasReturnsTwiceCall |= CI->canReturnTwice();
1043 void initializeCallbacks(
Module &M);
1045 bool doesDominateAllExits(
const Instruction *
I)
const {
1046 for (
auto Ret : RetVec) {
1047 if (!ASan.getDominatorTree().dominates(I,
Ret))
return false;
1080 AddressSanitizer,
"asan",
1081 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false,
1086 AddressSanitizer,
"asan",
1087 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false,
1092 bool UseAfterScope) {
1093 assert(!CompileKernel || Recover);
1094 return new AddressSanitizer(CompileKernel, Recover, UseAfterScope);
1100 AddressSanitizerModule,
"asan-module",
1101 "AddressSanitizer: detects use-after-free and out-of-bounds bugs." 1108 bool UseOdrIndicator) {
1109 assert(!CompileKernel || Recover);
1110 return new AddressSanitizerModule(CompileKernel, Recover, UseGlobalsGC,
1122 LocationMetadata MD) {
1149 if (G->
getName() ==
"__llvm_gcov_ctr")
1157 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
1158 if (Mapping.Offset == 0)
return Shadow;
1161 if (LocalDynamicShadow)
1162 ShadowBase = LocalDynamicShadow;
1165 if (Mapping.OrShadowOffset)
1166 return IRB.
CreateOr(Shadow, ShadowBase);
1168 return IRB.
CreateAdd(Shadow, ShadowBase);
1172 void AddressSanitizer::instrumentMemIntrinsic(
MemIntrinsic *
MI) {
1174 if (isa<MemTransferInst>(MI)) {
1176 isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
1180 }
else if (isa<MemSetInst>(MI)) {
1191 bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1192 auto PreviouslySeenAllocaInfo = ProcessedAllocas.find(&AI);
1194 if (PreviouslySeenAllocaInfo != ProcessedAllocas.end())
1195 return PreviouslySeenAllocaInfo->getSecond();
1197 bool IsInteresting =
1210 ProcessedAllocas[&AI] = IsInteresting;
1211 return IsInteresting;
1217 unsigned *Alignment,
1218 Value **MaybeMask) {
1223 if (LocalDynamicShadow == I)
1226 Value *PtrOperand =
nullptr;
1228 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
1232 *Alignment = LI->getAlignment();
1233 PtrOperand = LI->getPointerOperand();
1234 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(I)) {
1238 *Alignment =
SI->getAlignment();
1239 PtrOperand =
SI->getPointerOperand();
1240 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
1245 PtrOperand = RMW->getPointerOperand();
1251 PtrOperand = XCHG->getPointerOperand();
1252 }
else if (
auto CI = dyn_cast<CallInst>(I)) {
1254 if (
F && (
F->getName().startswith(
"llvm.masked.load.") ||
1255 F->getName().startswith(
"llvm.masked.store."))) {
1256 unsigned OpOffset = 0;
1257 if (
F->getName().startswith(
"llvm.masked.store.")) {
1269 auto BasePtr = CI->getOperand(0 + OpOffset);
1270 auto Ty = cast<PointerType>(BasePtr->getType())->getElementType();
1272 if (
auto AlignmentConstant =
1273 dyn_cast<ConstantInt>(CI->getOperand(1 + OpOffset)))
1274 *Alignment = (
unsigned)AlignmentConstant->getZExtValue();
1278 *MaybeMask = CI->getOperand(2 + OpOffset);
1279 PtrOperand = BasePtr;
1302 if (
auto AI = dyn_cast_or_null<AllocaInst>(PtrOperand))
1303 return isInterestingAlloca(*AI) ? AI :
nullptr;
1316 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) {
1317 if (!Cmp->isRelational())
return false;
1319 if (BO->getOpcode() != Instruction::Sub)
return false;
1334 void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1337 Function *
F = isa<ICmpInst>(
I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
1339 for (
Value *&i : Param) {
1340 if (i->getType()->isPointerTy())
1348 unsigned Alignment,
unsigned Granularity,
1350 Value *SizeArgument,
bool UseCalls,
1354 if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 ||
1356 (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8))
1357 return Pass->instrumentAddress(I, InsertBefore, Addr, TypeSize, IsWrite,
1358 nullptr, UseCalls, Exp);
1359 Pass->instrumentUnusualSizeOrAlignment(I, InsertBefore, Addr, TypeSize,
1360 IsWrite,
nullptr, UseCalls, Exp);
1366 Value *Addr,
unsigned Alignment,
1367 unsigned Granularity,
uint32_t TypeSize,
1368 bool IsWrite,
Value *SizeArgument,
1370 auto *VTy = cast<PointerType>(Addr->
getType())->getElementType();
1372 unsigned Num = VTy->getVectorNumElements();
1374 for (
unsigned Idx = 0; Idx < Num; ++Idx) {
1375 Value *InstrumentedAddress =
nullptr;
1377 if (
auto *Vector = dyn_cast<ConstantVector>(Mask)) {
1379 if (
auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
1380 if (Masked->isZero())
1390 InsertBefore = ThenTerm;
1394 InstrumentedAddress =
1397 Granularity, ElemTypeSize, IsWrite, SizeArgument,
1405 bool IsWrite =
false;
1406 unsigned Alignment = 0;
1407 uint64_t TypeSize = 0;
1408 Value *MaybeMask =
nullptr;
1410 isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask);
1431 isSafeAccess(ObjSizeVis, Addr, TypeSize)) {
1432 NumOptimizedAccessesToGlobalVar++;
1440 isSafeAccess(ObjSizeVis, Addr, TypeSize)) {
1441 NumOptimizedAccessesToStackVar++;
1447 NumInstrumentedWrites++;
1449 NumInstrumentedReads++;
1451 unsigned Granularity = 1 << Mapping.Scale;
1454 Alignment, Granularity, TypeSize, IsWrite,
1455 nullptr, UseCalls, Exp);
1458 IsWrite,
nullptr, UseCalls, Exp);
1463 Value *Addr,
bool IsWrite,
1464 size_t AccessSizeIndex,
1465 Value *SizeArgument,
1472 Call = IRB.
CreateCall(AsanErrorCallbackSized[IsWrite][0],
1473 {Addr, SizeArgument});
1475 Call = IRB.
CreateCall(AsanErrorCallbackSized[IsWrite][1],
1476 {Addr, SizeArgument, ExpVal});
1480 IRB.
CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1482 Call = IRB.
CreateCall(AsanErrorCallback[IsWrite][1][AccessSizeIndex],
1496 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1498 Value *LastAccessedByte =
1501 if (TypeSize / 8 > 1)
1511 void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1514 Value *SizeArgument,
bool UseCalls,
1524 IRB.
CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex],
1527 IRB.
CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1545 assert(cast<BranchInst>(TagCheckTerm)->isUnconditional());
1547 InsertBefore = TagCheckTerm;
1553 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1555 Value *ShadowValue =
1559 size_t Granularity = 1ULL << Mapping.Scale;
1567 assert(cast<BranchInst>(CheckTerm)->isUnconditional());
1570 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize);
1584 Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite,
1585 AccessSizeIndex, SizeArgument, Exp);
1593 void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1595 bool IsWrite,
Value *SizeArgument,
bool UseCalls,
uint32_t Exp) {
1601 IRB.
CreateCall(AsanMemoryAccessCallbackSized[IsWrite][0],
1604 IRB.
CreateCall(AsanMemoryAccessCallbackSized[IsWrite][1],
1610 instrumentAddress(I, InsertBefore, Addr, 8, IsWrite, Size,
false, Exp);
1611 instrumentAddress(I, InsertBefore, LastByte, 8, IsWrite, Size,
false, Exp);
1615 void AddressSanitizerModule::poisonOneInitializer(
Function &GlobalInit,
1623 IRB.
CreateCall(AsanPoisonGlobals, ModuleNameAddr);
1627 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
1631 void AddressSanitizerModule::createInitializerPoisonCalls(
1642 if (isa<ConstantAggregateZero>(
OP))
continue;
1651 poisonOneInitializer(*
F, ModuleName);
1656 bool AddressSanitizerModule::ShouldInstrumentGlobal(
GlobalVariable *G) {
1660 if (GlobalsMD.get(G).IsBlacklisted)
return false;
1661 if (!Ty->
isSized())
return false;
1669 if (G->
getAlignment() > MinRedzoneSizeForGlobal())
return false;
1675 if (!TargetTriple.isOSBinFormatCOFF()) {
1687 switch (
C->getSelectionKind()) {
1702 if (Section ==
"llvm.metadata")
return false;
1722 if (TargetTriple.isOSBinFormatCOFF() && Section.
contains(
'$')) {
1723 LLVM_DEBUG(
dbgs() <<
"Ignoring global in sorted section (contains '$'): " 1728 if (TargetTriple.isOSBinFormatMachO()) {
1730 unsigned TAA = 0, StubSize = 0;
1733 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize);
1734 assert(ErrorCode.empty() &&
"Invalid section specifier.");
1739 if (ParsedSegment ==
"__OBJC" ||
1740 (ParsedSegment ==
"__DATA" && ParsedSection.
startswith(
"__objc_"))) {
1741 LLVM_DEBUG(
dbgs() <<
"Ignoring ObjC runtime global: " << *G <<
"\n");
1752 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
1759 LLVM_DEBUG(
dbgs() <<
"Ignoring a cstring literal: " << *G <<
"\n");
1771 bool AddressSanitizerModule::ShouldUseMachOGlobalsSection()
const {
1772 if (!TargetTriple.isOSBinFormatMachO())
1775 if (TargetTriple.isMacOSX() && !TargetTriple.isMacOSXVersionLT(10, 11))
1777 if (TargetTriple.isiOS() && !TargetTriple.isOSVersionLT(9))
1779 if (TargetTriple.isWatchOS() && !TargetTriple.isOSVersionLT(2))
1785 StringRef AddressSanitizerModule::getGlobalMetadataSection()
const {
1786 switch (TargetTriple.getObjectFormat()) {
1795 void AddressSanitizerModule::initializeCallbacks(
Module &M) {
1800 kAsanPoisonGlobalsName, IRB.
getVoidTy(), IntptrTy));
1803 kAsanUnpoisonGlobalsName, IRB.
getVoidTy()));
1808 kAsanRegisterGlobalsName, IRB.
getVoidTy(), IntptrTy, IntptrTy));
1812 IntptrTy, IntptrTy));
1817 AsanRegisterImageGlobals =
1819 kAsanRegisterImageGlobalsName, IRB.
getVoidTy(), IntptrTy));
1822 AsanUnregisterImageGlobals =
1824 kAsanUnregisterImageGlobalsName, IRB.
getVoidTy(), IntptrTy));
1829 IntptrTy, IntptrTy, IntptrTy));
1834 IntptrTy, IntptrTy, IntptrTy));
1840 void AddressSanitizerModule::SetComdatForGlobalMetadata(
1854 Name += InternalSuffix;
1863 if (TargetTriple.isOSBinFormatCOFF()) {
1878 AddressSanitizerModule::CreateMetadataGlobal(
Module &M,
Constant *Initializer,
1880 auto Linkage = TargetTriple.isOSBinFormatMachO()
1884 M, Initializer->
getType(),
false, Linkage, Initializer,
1886 Metadata->
setSection(getGlobalMetadataSection());
1899 void AddressSanitizerModule::InstrumentGlobalsCOFF(
1905 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
1906 Constant *Initializer = MetadataInitializers[i];
1909 CreateMetadataGlobal(M, Initializer, G->
getName());
1914 unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->
getType());
1916 "global metadata will not be padded appropriately");
1919 SetComdatForGlobalMetadata(G, Metadata,
"");
1923 void AddressSanitizerModule::InstrumentGlobalsELF(
1926 const std::string &UniqueModuleId) {
1930 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
1933 CreateMetadataGlobal(M, MetadataInitializers[i], G->
getName());
1938 SetComdatForGlobalMetadata(G, Metadata, UniqueModuleId);
1943 if (!MetadataGlobals.empty())
1960 "__start_" + getGlobalMetadataSection());
1964 "__stop_" + getGlobalMetadataSection());
1976 IRB_Dtor.
CreateCall(AsanUnregisterElfGlobals,
1982 void AddressSanitizerModule::InstrumentGlobalsMachO(
1993 for (
size_t i = 0; i < ExtendedGlobals.
size(); i++) {
1994 Constant *Initializer = MetadataInitializers[i];
1997 CreateMetadataGlobal(M, Initializer, G->
getName());
2001 auto LivenessBinder =
2007 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
2008 LivenessGlobals[i] = Liveness;
2015 if (!LivenessGlobals.empty())
2035 IRB_Dtor.
CreateCall(AsanUnregisterImageGlobals,
2039 void AddressSanitizerModule::InstrumentGlobalsWithMetadataArray(
2043 unsigned N = ExtendedGlobals.
size();
2053 if (Mapping.Scale > 3)
2054 AllGlobals->setAlignment(1ULL << Mapping.Scale);
2073 bool AddressSanitizerModule::InstrumentGlobals(
IRBuilder<> &IRB,
Module &M,
bool *CtorComdat) {
2074 *CtorComdat =
false;
2080 if (ShouldInstrumentGlobal(&G)) GlobalsToChange.
push_back(&G);
2083 size_t n = GlobalsToChange.
size();
2103 IntptrTy, IntptrTy, IntptrTy);
2107 bool HasDynamicallyInitializedGlobals =
false;
2114 for (
size_t i = 0; i < n; i++) {
2115 static const uint64_t kMaxGlobalRedzone = 1 << 18;
2118 auto MD = GlobalsMD.get(G);
2123 M, MD.Name.
empty() ? NameForGlobal : MD.Name,
2128 uint64_t MinRZ = MinRedzoneSizeForGlobal();
2132 MinRZ, std::min(kMaxGlobalRedzone, (SizeInBytes / MinRZ / 4) * MinRZ));
2133 uint64_t RightRedzoneSize =
RZ;
2135 if (SizeInBytes % MinRZ) RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ);
2136 assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0);
2149 "",
G, G->getThreadLocalMode());
2159 if (TargetTriple.isOSBinFormatMachO() && !G->hasSection() &&
2162 if (Seq && Seq->isCString())
2163 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
2169 G->getDebugInfo(GVs);
2170 for (
auto *GV : GVs)
2180 G->eraseFromParent();
2181 NewGlobals[i] = NewGlobal;
2184 if (!MD.SourceLoc.empty()) {
2194 bool CanUsePrivateAliases =
2195 TargetTriple.isOSBinFormatELF() || TargetTriple.isOSBinFormatMachO() ||
2196 TargetTriple.isOSBinFormatWasm();
2197 if (CanUsePrivateAliases && UsePrivateAlias) {
2200 InstrumentedGlobal =
2208 }
else if (UseOdrIndicator) {
2211 auto *ODRIndicatorSym =
2214 kODRGenPrefix + NameForGlobal,
nullptr,
2220 ODRIndicatorSym->setAlignment(1);
2221 ODRIndicator = ODRIndicatorSym;
2234 if (
ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals =
true;
2238 Initializers[i] = Initializer;
2244 for (
size_t i = 0; i < n; i++) {
2251 std::string ELFUniqueModuleId =
2255 if (!ELFUniqueModuleId.empty()) {
2256 InstrumentGlobalsELF(IRB, M, NewGlobals, Initializers, ELFUniqueModuleId);
2258 }
else if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) {
2259 InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
2260 }
else if (UseGlobalsGC && ShouldUseMachOGlobalsSection()) {
2261 InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
2263 InstrumentGlobalsWithMetadataArray(IRB, M, NewGlobals, Initializers);
2267 if (HasDynamicallyInitializedGlobals)
2268 createInitializerPoisonCalls(M, ModuleName);
2274 int AddressSanitizerModule::GetAsanVersion(
const Module &M)
const {
2280 Version += (LongSize == 32 && isAndroid);
2284 bool AddressSanitizerModule::runOnModule(
Module &M) {
2290 initializeCallbacks(M);
2297 std::string VersionCheckName =
2300 M, kAsanModuleCtorName, kAsanInitName, {},
2301 {}, VersionCheckName);
2303 bool CtorComdat =
true;
2304 bool Changed =
false;
2307 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
2308 Changed |= InstrumentGlobals(IRB, M, &CtorComdat);
2314 if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) {
2318 if (AsanDtorFunction) {
2325 if (AsanDtorFunction)
2332 void AddressSanitizer::initializeCallbacks(
Module &M) {
2336 for (
int Exp = 0; Exp < 2; Exp++) {
2337 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
2338 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
2339 const std::string ExpStr = Exp ?
"exp_" :
"";
2340 const std::string EndingStr = Recover ?
"_noabort" :
"";
2347 Args1.push_back(ExpType);
2349 AsanErrorCallbackSized[AccessIsWrite][Exp] =
2351 kAsanReportErrorTemplate + ExpStr + TypeStr +
"_n" + EndingStr,
2354 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
2360 AccessSizeIndex++) {
2361 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
2362 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2364 kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr,
2367 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
2375 const std::string MemIntrinCallbackPrefix =
2378 MemIntrinCallbackPrefix +
"memmove", IRB.
getInt8PtrTy(),
2381 MemIntrinCallbackPrefix +
"memcpy", IRB.
getInt8PtrTy(),
2384 MemIntrinCallbackPrefix +
"memset", IRB.
getInt8PtrTy(),
2391 kAsanPtrCmp, IRB.
getVoidTy(), IntptrTy, IntptrTy));
2393 kAsanPtrSub, IRB.
getVoidTy(), IntptrTy, IntptrTy));
2398 if (Mapping.InGlobal)
2404 bool AddressSanitizer::doInitialization(
Module &M) {
2417 bool AddressSanitizer::doFinalization(
Module &M) {
2422 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &
F) {
2430 if (F.
getName().
find(
" load]") != std::string::npos) {
2440 void AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &F) {
2446 if (Mapping.InGlobal) {
2454 LocalDynamicShadow =
2455 IRB.
CreateCall(Asm, {AsanShadowGlobal},
".asan.shadow");
2457 LocalDynamicShadow =
2462 kAsanShadowMemoryDynamicAddress, IntptrTy);
2463 LocalDynamicShadow = IRB.
CreateLoad(GlobalDynamicAddress);
2467 void AddressSanitizer::markEscapedLocalAllocas(
Function &F) {
2472 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
2487 "non-static alloca arg to localescape");
2488 ProcessedAllocas[AI] =
false;
2500 bool FunctionModified =
false;
2505 if (maybeInsertAsanInitAtFunctionEntry(F))
2506 FunctionModified =
true;
2514 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
2516 FunctionStateRAII CleanupObj(
this);
2518 maybeInsertDynamicShadowAtFunctionEntry(F);
2522 markEscapedLocalAllocas(F);
2536 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
2539 for (
auto &BB : F) {
2541 TempsToInstrument.
clear();
2542 int NumInsnsPerBB = 0;
2543 for (
auto &Inst : BB) {
2544 if (LooksLikeCodeInBug11395(&Inst))
return false;
2545 Value *MaybeMask =
nullptr;
2546 if (
Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
2547 &Alignment, &MaybeMask)) {
2553 if (TempsToInstrument.
count(Addr))
2556 if (!TempsToInstrument.
insert(Addr).second)
2562 PointerComparisonsOrSubtracts.
push_back(&Inst);
2564 }
else if (isa<MemIntrinsic>(Inst)) {
2567 if (isa<AllocaInst>(Inst)) NumAllocas++;
2571 TempsToInstrument.
clear();
2574 if (
CallInst *CI = dyn_cast<CallInst>(&Inst))
2587 const DataLayout &DL = F.getParent()->getDataLayout();
2593 int NumInstrumented = 0;
2594 for (
auto Inst : ToInstrument) {
2597 if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
2598 instrumentMop(ObjSizeVis, Inst, UseCalls,
2599 F.getParent()->getDataLayout());
2601 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
2606 FunctionStackPoisoner FSP(F, *
this);
2607 bool ChangedStack = FSP.runOnFunction();
2611 for (
auto CI : NoReturnCalls) {
2616 for (
auto Inst : PointerComparisonsOrSubtracts) {
2617 instrumentPointerComparisonOrSubtraction(Inst);
2621 if (NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty())
2622 FunctionModified =
true;
2624 LLVM_DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" " 2627 return FunctionModified;
2633 bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *I) {
2634 if (LongSize != 32)
return false;
2642 void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
2645 std::string Suffix =
itostr(i);
2653 if (ASan.UseAfterScope) {
2656 IntptrTy, IntptrTy));
2659 IntptrTy, IntptrTy));
2662 for (
size_t Val : {0x00, 0xf1, 0xf2, 0xf3, 0xf5, 0xf8}) {
2663 std::ostringstream
Name;
2665 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
2666 AsanSetShadowFunc[Val] =
2668 Name.str(), IRB.
getVoidTy(), IntptrTy, IntptrTy));
2672 kAsanAllocaPoison, IRB.
getVoidTy(), IntptrTy, IntptrTy));
2673 AsanAllocasUnpoisonFunc =
2675 kAsanAllocasUnpoison, IRB.
getVoidTy(), IntptrTy, IntptrTy));
2680 size_t Begin,
size_t End,
2682 Value *ShadowBase) {
2686 const size_t LargestStoreSizeInBytes =
2687 std::min<size_t>(
sizeof(uint64_t), ASan.LongSize / 8);
2695 for (
size_t i = Begin; i < End;) {
2696 if (!ShadowMask[i]) {
2702 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
2704 while (StoreSizeInBytes > End - i)
2705 StoreSizeInBytes /= 2;
2708 for (
size_t j = StoreSizeInBytes - 1; j && !ShadowMask[i + j]; --j) {
2709 while (j <= StoreSizeInBytes / 2)
2710 StoreSizeInBytes /= 2;
2714 for (
size_t j = 0; j < StoreSizeInBytes; j++) {
2716 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
2718 Val = (Val << 8) | ShadowBytes[i + j];
2722 Value *Poison = IRB.
getIntN(StoreSizeInBytes * 8, Val);
2726 i += StoreSizeInBytes;
2733 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
2738 size_t Begin,
size_t End,
2741 size_t Done = Begin;
2742 for (
size_t i = Begin, j = Begin + 1; i < End; i = j++) {
2743 if (!ShadowMask[i]) {
2747 uint8_t Val = ShadowBytes[i];
2748 if (!AsanSetShadowFunc[Val])
2752 for (; j < End && ShadowMask[j] && Val == ShadowBytes[j]; ++j) {
2756 copyToShadowInline(ShadowMask, ShadowBytes, Done, i, IRB, ShadowBase);
2764 copyToShadowInline(ShadowMask, ShadowBytes, Done, End, IRB, ShadowBase);
2772 for (
int i = 0;; i++, MaxSize *= 2)
2773 if (LocalStackSize <= MaxSize)
return i;
2777 void FunctionStackPoisoner::copyArgsPassedByValToAllocas() {
2779 if (CopyInsertPoint == ASan.LocalDynamicShadow) {
2787 if (
Arg.hasByValAttr()) {
2789 unsigned Align =
Arg.getParamAlignment();
2808 Value *ValueIfFalse) {
2817 Value *FunctionStackPoisoner::createAllocaForLayout(
2826 nullptr,
"MyAlloca");
2835 void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
2838 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
2843 void FunctionStackPoisoner::processDynamicAllocas() {
2845 assert(DynamicAllocaPoisonCallVec.empty());
2850 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
2853 assert(ASan.isInterestingAlloca(*APC.AI));
2854 assert(!APC.AI->isStaticAlloca());
2857 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
2864 createDynamicAllocasInitStorage();
2865 for (
auto &AI : DynamicAllocaVec)
2866 handleDynamicAllocaCall(AI);
2867 unpoisonDynamicAllocas();
2870 void FunctionStackPoisoner::processStaticAllocas() {
2871 if (AllocaVec.empty()) {
2872 assert(StaticAllocaPoisonCallVec.empty());
2876 int StackMallocIdx = -1;
2888 auto InsBeforeB = InsBefore->
getParent();
2890 for (
auto *AI : StaticAllocasToMoveUp)
2895 if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore);
2898 SVD.
reserve(AllocaVec.size());
2901 ASan.getAllocaSizeInBytes(*AI),
2912 size_t Granularity = 1ULL << Mapping.Scale;
2913 size_t MinHeaderSize =
std::max((
size_t)ASan.LongSize / 2, Granularity);
2919 for (
auto &Desc : SVD)
2920 AllocaToSVDMap[Desc.AI] = &Desc;
2923 for (
const auto &APC : StaticAllocaPoisonCallVec) {
2926 assert(ASan.isInterestingAlloca(*APC.AI));
2927 assert(APC.AI->isStaticAlloca());
2930 Desc.LifetimeSize = Desc.Size;
2932 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().
get()) {
2933 if (LifetimeLoc->getFile() == FnLoc->getFile())
2934 if (
unsigned Line = LifetimeLoc->getLine())
2935 Desc.Line = std::min(Desc.Line ? Desc.Line : Line, Line);
2952 DoDynamicAlloca &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall;
2953 DoStackMalloc &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall;
2955 Value *StaticAlloca =
2956 DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L,
false);
2959 Value *LocalStackBase;
2960 Value *LocalStackBaseAlloca;
2963 if (DoStackMalloc) {
2964 LocalStackBaseAlloca =
2965 IRB.
CreateAlloca(IntptrTy,
nullptr,
"asan_local_stack_base");
2971 kAsanOptionDetectUseAfterReturn, IRB.
getInt32Ty());
2972 Value *UseAfterReturnIsEnabled =
2981 Value *FakeStackValue =
2982 IRBIf.
CreateCall(AsanStackMallocFunc[StackMallocIdx],
2986 FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term,
2989 Value *NoFakeStack =
2994 Value *AllocaValue =
2995 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
2999 LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack);
3001 IRB.
CreateStore(LocalStackBase, LocalStackBaseAlloca);
3008 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
3009 LocalStackBaseAlloca = LocalStackBase;
3014 for (
const auto &Desc : SVD) {
3049 Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB);
3052 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
3054 if (!StaticAllocaPoisonCallVec.empty()) {
3058 for (
const auto &APC : StaticAllocaPoisonCallVec) {
3065 copyToShadow(ShadowAfterScope,
3066 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
3075 for (
auto Ret : RetVec) {
3080 if (DoStackMalloc) {
3081 assert(StackMallocIdx >= 0);
3098 if (StackMallocIdx <= 4) {
3102 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
3115 AsanStackFreeFunc[StackMallocIdx],
3120 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
3122 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
3130 void FunctionStackPoisoner::poisonAlloca(
Value *V, uint64_t
Size,
3136 DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
3137 {AddrArg, SizeArg});
3150 if (
AllocaInst *AI = dyn_cast<AllocaInst>(V))
3152 return ASan.isInterestingAlloca(*AI) ? AI :
nullptr;
3155 AllocaForValueMapTy::iterator I = AllocaForValue.find(V);
3156 if (I != AllocaForValue.end())
return I->second;
3159 AllocaForValue[V] =
nullptr;
3162 Res = findAllocaForValue(CI->getOperand(0));
3163 else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
3164 for (
Value *IncValue : PN->incoming_values()) {
3166 if (IncValue == PN)
continue;
3167 AllocaInst *IncValueAI = findAllocaForValue(IncValue);
3169 if (IncValueAI ==
nullptr || (Res !=
nullptr && IncValueAI != Res))
3174 Res = findAllocaForValue(EP->getPointerOperand());
3176 LLVM_DEBUG(
dbgs() <<
"Alloca search canceled on unknown instruction: " << *V
3179 if (Res) AllocaForValue[V] = Res;
3183 void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
3187 const uint64_t AllocaRedzoneMask = kAllocaRzSize - 1;
3197 const unsigned ElementSize =
3230 IRB.
CreateCall(AsanAllocaPoisonFunc, {NewAddress, OldSize});
3249 Value *Addr, uint64_t TypeSize)
const {
3251 if (!ObjSizeVis.
bothKnown(SizeOffset))
return false;
3252 uint64_t Size = SizeOffset.first.getZExtValue();
3253 int64_t
Offset = SizeOffset.second.getSExtValue();
3258 return Offset >= 0 && Size >= uint64_t(Offset) &&
3259 Size - uint64_t(Offset) >= TypeSize / 8;
void setVisibility(VisibilityTypes V)
Pass interface - Implemented by all 'passes'.
static const uint64_t kMyriadCacheBitMask32
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static bool isValueValidForType(Type *Ty, uint64_t V)
This static method returns true if the type Ty is big enough to represent the value V...
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue *> Values)
Adds global values to the llvm.compiler.used list.
Return a value (possibly void), from a function.
StringRef getSection() const
Get the custom section of this global if it has one.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static const char *const kAsanSetShadowPrefix
unsigned getAlignment() const
static const uint64_t kIOSShadowOffset32
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
ThreadLocalMode getThreadLocalMode() const
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
Function * declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type *> InitArgTypes)
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
bool hasLocalLinkage() const
static const uint64_t kFreeBSD_ShadowOffset64
static cl::opt< bool > ClInitializers("asan-initialization-order", cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(true))
DILocation * get() const
Get the underlying DILocation.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents an incoming formal argument to a Function.
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Base class for instruction visitors.
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, bool DerefBefore, int Offset, bool DerefAfter)
Replaces llvm.dbg.declare instruction when the alloca it describes is replaced with a new value...
Function * checkSanitizerInterfaceFunction(Constant *FuncOrBitcast)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
bool hasPrivateLinkage() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
static size_t RedzoneSizeForScale(int MappingScale)
static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize, bool IsKasan)
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
A Module instance is used to store all the information related to an LLVM module. ...
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant *> IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
void setAlignment(unsigned Align)
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Available for inspection, not emission.
void push_back(const T &Elt)
static const char *const kAsanUnregisterElfGlobalsName
static const uintptr_t kCurrentStackFrameMagic
This class represents a function call, abstracting a target machine's calling convention.
static cl::opt< bool > ClUsePrivateAlias("asan-use-private-alias", cl::desc("Use private aliases for global variables"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClUseAfterReturn("asan-use-after-return", cl::desc("Check stack-use-after-return"), cl::Hidden, cl::init(true))
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
static bool isInterestingPointerComparisonOrSubtraction(Instruction *I)
static const char *const kODRGenPrefix
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM...
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
bool isWatchOS() const
Is this an Apple watchOS triple.
Like Internal, but omit from symbol table.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables...
Externally visible function.
static cl::opt< bool > ClForceDynamicShadow("asan-force-dynamic-shadow", cl::desc("Load shadow address into a local variable for each function"), cl::Hidden, cl::init(false))
bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
The data referenced by the COMDAT must be the same size.
static cl::opt< int > ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClRecover("asan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
GlobalVariable * getGlobalVariable(StringRef Name) const
Look up the specified global variable in the module symbol table.
INITIALIZE_PASS_BEGIN(AddressSanitizer, "asan", "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) INITIALIZE_PASS_END(AddressSanitizer
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
STATISTIC(NumFunctions, "Total number of functions")
SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
const MDOperand & getOperand(unsigned I) const
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
An instruction for reading from memory.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
This defines the Use class.
void reserve(size_type N)
void setAlignment(unsigned Align)
static cl::opt< unsigned long long > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
static Constant * get(ArrayType *T, ArrayRef< Constant *> V)
static const uint64_t kMyriadDDRTag
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align, bool isVolatile=false)
iterator begin()
Instruction iterator methods.
static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I, Instruction *InsertBefore, Value *Addr, unsigned Alignment, unsigned Granularity, uint32_t TypeSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp)
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * getArgOperand(unsigned i) const
static const uint64_t kDefaultShadowScale
static const char *const kAsanShadowMemoryDynamicAddress
static const int kAsanStackUseAfterReturnMagic
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool doesNotReturn() const
Determine if the call cannot return.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Type * getPointerElementType() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
This is the base class for all instructions that perform data casts.
PointerType * getType() const
Overload to return most specific pointer type.
Class to represent struct types.
LLVMContext & getContext() const
Get the global data context.
static const uint64_t kSmallX86_64ShadowOffsetBase
static const uint64_t kLinuxKasan_ShadowOffset64
A Use represents the edge between a Value definition and its users.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This file contains the simple types necessary to represent the attributes associated with functions a...
InstrTy * getInstruction() const
The linker may choose any COMDAT.
static const char *const kAsanAllocasUnpoison
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void setName(const Twine &Name)
Change the name of the value.
static const char *const kAsanModuleCtorName
static const uint64_t kIOSSimShadowOffset64
static const uint64_t kMyriadMemoryOffset32
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
static const uint64_t kSmallX86_64ShadowOffsetAlignMask
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static const char *const kAsanPoisonStackMemoryName
ModulePass * createAddressSanitizerModulePass(bool CompileKernel=false, bool Recover=false, bool UseGlobalsGC=true, bool UseOdrIndicator=true)
Type * getType() const
All values are typed, get the type of this value.
SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
std::string itostr(int64_t X)
ConstantDataSequential - A vector or array constant whose element type is a simple 1/2/4/8-byte integ...
static const char *const kSanCovGenPrefix
bool isSwiftError() const
Return true if this value is a swifterror value.
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
static cl::opt< bool > ClUseOdrIndicator("asan-use-odr-indicator", cl::desc("Use odr indicators to improve ODR reporting"), cl::Hidden, cl::init(false))
Class to represent array types.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
static const int kMaxAsanStackMallocSizeClass
static const uint64_t kIOSSimShadowOffset32
static cl::opt< bool > ClOptSameTemp("asan-opt-same-temp", cl::desc("Instrument the same temp just once"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClEnableKasan("asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static const uint64_t kAsanCtorAndDtorPriority
void setComdat(Comdat *C)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const APInt & getValue() const
Return the constant as an APInt value reference.
bool isLittleEndian() const
Layout endianness...
static const uint64_t kWindowsShadowOffset64
iterator_range< User::op_iterator > arg_operands()
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
bool isiOS() const
Is this an iOS triple.
An instruction for storing to memory.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static const uint64_t kMyriadTagShift
LinkageTypes getLinkage() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void takeName(Value *V)
Transfer the name from V to this value.
static cl::opt< bool > ClAlwaysSlowPath("asan-always-slow-path", cl::desc("use instrumentation with slow path for all accesses"), cl::Hidden, cl::init(false))
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
iterator_range< op_iterator > operands()
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
static const uint64_t kDefaultShadowOffset32
Value * getOperand(unsigned i) const
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
static void instrumentMaskedLoadOrStore(AddressSanitizer *Pass, const DataLayout &DL, Type *IntptrTy, Value *Mask, Instruction *I, Value *Addr, unsigned Alignment, unsigned Granularity, uint32_t TypeSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
bool isOSWindows() const
Tests whether the OS is Windows.
ExternalWeak linkage description.
const BasicBlock & getEntryBlock() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
static const size_t kNumberOfAccessSizes
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
static bool runOnFunction(Function &F, bool PostInlining)
static const char *const kAsanGlobalsRegisteredFlagName
initializer< Ty > init(const Ty &Val)
No other Module may specify this COMDAT.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
static const char *const kAsanPtrCmp
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static std::string ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
Parse the section specifier indicated by "Spec".
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
DLLStorageClassTypes getDLLStorageClass() const
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
VisibilityTypes getVisibility() const
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
std::pair< Function *, Function * > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type *> InitArgTypes, ArrayRef< Value *> InitArgs, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function, and calls sanitizer's init function from it.
VendorType getVendor() const
getVendor - Get the parsed vendor type of this triple.
This is an important class for using LLVM in a threaded context.
DISubprogram * getSubprogram() const
Get the attached subprogram.
Conditional or Unconditional Branch instruction.
static const size_t kMinStackMallocSize
size_t size() const
size - Get the array size.
This function has undefined behavior.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Resume the propagation of an exception.
static const char *const kAsanInitName
static const char *const kAsanStackFreeNameTemplate
static const uint64_t kNetBSD_ShadowOffset32
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
bool isPointerTy() const
True if this is an instance of PointerType.
static const uint64_t kMIPS32_ShadowOffset32
const Instruction & front() const
static const char *const kAsanOptionDetectUseAfterReturn
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static const uint64_t kFreeBSD_ShadowOffset32
static const uint64_t kAArch64_ShadowOffset64
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
Represent the analysis usage information of a pass.
bool isLifetimeStartOrEnd() const
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
static Type * getVoidTy(LLVMContext &C)
bool isAndroidVersionLT(unsigned Major) const
bool isPS4CPU() const
Tests whether the target is the PS4 CPU.
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
FunctionPass class - This class is used to implement most global optimizations.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Constant * get(StructType *T, ArrayRef< Constant *> V)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
ASanStackFrameLayout ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, size_t Granularity, size_t MinHeaderSize)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseGlobalsGC("asan-globals-live-support", cl::desc("Use linker features to support dead " "code stripping of globals"), cl::Hidden, cl::init(true))
static const uintptr_t kRetiredStackFrameMagic
The data referenced by the COMDAT must be the same.
llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
static const uint64_t kMyriadShadowScale
static const char *const kAsanGenPrefix
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...
static const char *const kAsanPtrSub
static cl::opt< int > ClMaxInsnsToInstrumentPerBB("asan-max-ins-per-bb", cl::init(10000), cl::desc("maximal number of instructions to instrument in any given BB"), cl::Hidden)
S_CSTRING_LITERALS - Section with literal C strings.
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
static cl::opt< uint32_t > ClMaxInlinePoisoningSize("asan-max-inline-poisoning-size", cl::desc("Inline shadow poisoning for blocks up to the given size in bytes."), cl::Hidden, cl::init(64))
const Value * getArraySize() const
Get the number of elements allocated.
std::pair< APInt, APInt > SizeOffsetType
static wasm::ValType getType(const TargetRegisterClass *RC)
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
static const uint64_t kWindowsShadowOffset32
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void initializeAddressSanitizerPass(PassRegistry &)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Triple - Helper class for working with autoconf configuration names.
static const char *const kAsanRegisterGlobalsName
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static const uint64_t kDynamicShadowSentinel
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
print lazy value Lazy Value Info Printer Pass
This is the common base class for memset/memcpy/memmove.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
This is the shared class of boolean and integer constants.
void setSelectionKind(SelectionKind Val)
static const char *const kAsanStackMallocNameTemplate
static const char *const kAsanUnpoisonStackMemoryName
Evaluate the size and offset of an object pointed to by a Value* statically.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
bool hasSection() const
Check if this global has a custom object file section.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
bool isOSLinux() const
Tests whether the OS is Linux.
static const uint64_t kDefaultShadowOffset64
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static cl::opt< int > ClDebugStack("asan-debug-stack", cl::desc("debug stack"), cl::Hidden, cl::init(0))
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
CallInst * CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
The linker will choose the largest COMDAT.
GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, const char *NamePrefix="")
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.
static cl::opt< bool > ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden, cl::init(false))
static bool isPointerOperand(Value *V)
static cl::opt< int > ClInstrumentationWithCallsThreshold("asan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented contains more than " "this number of memory accesses, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(7000))
void setLinkage(LinkageTypes LT)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
SizeOffsetType compute(Value *V)
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
ConstantArray - Constant Array Declarations.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1', drop it.
static const uint64_t kSystemZ_ShadowOffset64
static GlobalVariable * createPrivateGlobalForSourceLoc(Module &M, LocationMetadata MD)
Create a global describing a source location.
LinkageTypes
An enumeration for the kinds of linkage for global values.
static cl::opt< bool > ClWithIfuncSuppressRemat("asan-with-ifunc-suppress-remat", cl::desc("Suppress rematerialization of dynamic shadow address by passing " "it through inline asm in prologue."), cl::Hidden, cl::init(true))
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
void setMetadata(unsigned KindID, MDNode *MD)
Set a particular kind of metadata attachment.
amdgpu Simplify well known AMD library false Value Value * Arg
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
const Comdat * getComdat() const
void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
static const uint64_t kMyriadMemorySize32
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
unsigned getNumArgOperands() const
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool isInlineAsm() const
Check if this call is an inline asm statement.
static const uint64_t kMIPS64_ShadowOffset64
Constant * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
void setUnnamedAddr(UnnamedAddr Val)
static IntegerType * getInt32Ty(LLVMContext &C)
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
static int StackMallocSizeClass(uint64_t LocalStackSize)
LLVM_NODISCARD bool empty() const
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
static const char *const kAsanRegisterElfGlobalsName
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value...
StringRef getName() const
Return a constant reference to the value's name.
bool hasExactDefinition() const
Return true if this global has an exact defintion.
void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
const Function * getParent() const
Return the enclosing method, or null if none.
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Type * getValueType() const
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
static const uint64_t kNetBSD_ShadowOffset64
static const uint64_t kNetBSDKasan_ShadowOffset64
Rename collisions when linking (static functions).
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...
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
static const uint64_t kPS4CPU_ShadowOffset64
static const char *const kAsanModuleDtorName
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
const std::string to_string(const T &Value)
static uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
static const char *const kAsanUnregisterGlobalsName
iterator_range< df_iterator< T > > depth_first(const T &G)
static const char *const kAsanUnpoisonGlobalsName
bool isArrayAllocation() const
Return true if there is an allocation size parameter to the allocation instruction that is not 1...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const BasicBlock & front() const
static bool bothKnown(const SizeOffsetType &SizeOffset)
static const char *const kAsanPoisonGlobalsName
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
void setAlignment(unsigned Align)
INITIALIZE_PASS(AddressSanitizerModule, "asan-module", "AddressSanitizer: detects use-after-free and out-of-bounds bugs." "ModulePass", false, false) ModulePass *llvm
static const uint64_t kPPC64_ShadowOffset64
static const unsigned kAllocaRzSize
bool hasInitializer() const
Definitions have initializers, declarations don't.
static cl::opt< bool > ClRedzoneByvalArgs("asan-redzone-byval-args", cl::desc("Create redzones for byval " "arguments (extra copy " "required)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static const char *const kAsanUnregisterImageGlobalsName
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static const Function * getParent(const Value *V)
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool isAndroid() const
Tests whether the target is Android.
static const char *const kAsanRegisterImageGlobalsName
static Constant * getAnon(ArrayRef< Constant *> V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
FunctionPass * createAddressSanitizerFunctionPass(bool CompileKernel=false, bool Recover=false, bool UseAfterScope=false)
static const char *const kAsanAllocaPoison
static const char *const kAsanHandleNoReturnName
iterator_range< global_iterator > globals()
static const size_t kMaxStackMallocSize
StringRef - Represent a constant reference to a string, i.e.
Various options to control the behavior of getObjectSize.
Legacy analysis pass which computes a DominatorTree.
static cl::opt< bool > ClOptStack("asan-opt-stack", cl::desc("Don't instrument scalar stack variables"), cl::Hidden, cl::init(false))
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
static const char *const kAsanVersionCheckNamePrefix
static cl::opt< unsigned > ClRealignStack("asan-realign-stack", cl::desc("Realign stack to the value of this flag (power of two)"), cl::Hidden, cl::init(32))
unsigned getNumOperands() const
Return number of MDNode operands.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static cl::opt< bool > ClInstrumentDynamicAllocas("asan-instrument-dynamic-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(true))
void setSection(StringRef S)
Change the section for this global.
static 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...
bool isARM() const
Tests whether the target is ARM (little and big endian).
std::vector< uint32_t > Metadata
PAL metadata represented as a vector.
iterator_range< arg_iterator > args()
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
SmallVector< uint8_t, 64 > GetShadowBytes(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
static const char *const kAsanReportErrorTemplate