43 #include "llvm/Support/DataTypes.h"
61 #include <system_error>
65 #define DEBUG_TYPE "asan"
98 "__asan_unregister_globals";
100 "__asan_register_image_globals";
102 "__asan_unregister_image_globals";
107 "__asan_version_mismatch_check_v8";
119 "__asan_poison_stack_memory";
121 "__asan_unpoison_stack_memory";
123 "__asan_globals_registered";
126 "__asan_option_detect_stack_use_after_return";
129 "__asan_shadow_memory_dynamic_address";
141 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
145 cl::desc(
"Enable recovery mode (continue-after-error)."),
150 cl::desc(
"instrument read instructions"),
153 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
156 "asan-instrument-atomics",
160 "asan-always-slow-path",
164 "asan-force-dynamic-shadow",
165 cl::desc(
"Load shadow address into a local variable for each function"),
173 "asan-max-ins-per-bb",
cl::init(10000),
174 cl::desc(
"maximal number of instructions to instrument in any given BB"),
180 "asan-max-inline-poisoning-size",
182 "Inline shadow poisoning for blocks up to the given size in bytes."),
185 cl::desc(
"Check stack-use-after-return"),
188 cl::desc(
"Check stack-use-after-scope"),
195 cl::desc(
"Handle C++ initializer order"),
198 "asan-detect-invalid-pointer-pair",
202 "asan-realign-stack",
203 cl::desc(
"Realign stack to the value of this flag (power of two)"),
206 "asan-instrumentation-with-call-threshold",
208 "If the function being instrumented contains more than "
209 "this number of memory accesses, use callbacks instead of "
210 "inline checks (-1 means never use callbacks)."),
213 "asan-memory-access-callback-prefix",
218 cl::desc(
"instrument dynamic allocas"),
221 "asan-skip-promotable-allocas",
229 cl::desc(
"scale of asan shadow mapping"),
232 "asan-mapping-offset",
241 "asan-opt-same-temp",
cl::desc(
"Instrument the same temp just once"),
244 cl::desc(
"Don't instrument scalar globals"),
247 "asan-opt-stack",
cl::desc(
"Don't instrument scalar stack variables"),
251 "asan-stack-dynamic-alloca",
256 "asan-force-experiment",
262 cl::desc(
"Use private aliases for global"
268 cl::desc(
"Use linker features to support dead "
269 "code stripping of globals "
285 STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
286 STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
287 STATISTIC(NumOptimizedAccessesToGlobalVar,
288 "Number of optimized accesses to global vars");
289 STATISTIC(NumOptimizedAccessesToStackVar,
290 "Number of optimized accesses to stack vars");
294 struct LocationMetadata {
299 LocationMetadata() : Filename(), LineNo(0), ColumnNo(0) {}
301 bool empty()
const {
return Filename.empty(); }
308 mdconst::extract<ConstantInt>(MDN->
getOperand(1))->getLimitedValue();
310 mdconst::extract<ConstantInt>(MDN->
getOperand(2))->getLimitedValue();
315 class GlobalsMetadata {
318 Entry() : SourceLoc(),
Name(), IsDynInit(
false), IsBlacklisted(
false) {}
319 LocationMetadata SourceLoc;
325 GlobalsMetadata() : inited_(
false) {}
336 if (!Globals)
return;
337 for (
auto MDN : Globals->
operands()) {
340 auto *GV = mdconst::extract_or_null<GlobalVariable>(MDN->
getOperand(0));
345 Entry &
E = Entries[GV];
346 if (
auto *Loc = cast_or_null<MDNode>(MDN->
getOperand(1)))
347 E.SourceLoc.parse(Loc);
349 E.Name =
Name->getString();
351 mdconst::extract<ConstantInt>(MDN->
getOperand(3));
352 E.IsDynInit |= IsDynInit->
isOne();
354 mdconst::extract<ConstantInt>(MDN->
getOperand(4));
355 E.IsBlacklisted |= IsBlacklisted->
isOne();
361 auto Pos = Entries.find(
G);
362 return (Pos != Entries.end()) ? Pos->second : Entry();
372 struct ShadowMapping {
378 static ShadowMapping getShadowMapping(
Triple &TargetTriple,
int LongSize,
380 bool IsAndroid = TargetTriple.
isAndroid();
396 ShadowMapping Mapping;
398 if (LongSize == 32) {
421 else if (IsLinux && IsX86_64) {
426 }
else if (IsWindows && IsX86_64) {
459 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ
460 && !(Mapping.Offset & (Mapping.Offset - 1))
466 static size_t RedzoneSizeForScale(
int MappingScale) {
469 return std::max(32U, 1U << MappingScale);
474 explicit AddressSanitizer(
bool CompileKernel =
false,
bool Recover =
false,
475 bool UseAfterScope =
false)
479 LocalDynamicShadow(nullptr) {
483 return "AddressSanitizerFunctionPass";
489 uint64_t getAllocaSizeInBytes(
const AllocaInst &AI)
const {
490 uint64_t ArraySize = 1;
493 assert(CI &&
"non-constant array size");
497 uint64_t SizeInBytes =
499 return SizeInBytes * ArraySize;
502 bool isInterestingAlloca(
const AllocaInst &AI);
509 uint64_t *TypeSize,
unsigned *Alignment,
510 Value **MaybeMask =
nullptr);
513 void instrumentPointerComparisonOrSubtraction(
Instruction *
I);
520 Value *SizeArgument,
bool UseCalls,
525 bool IsWrite,
size_t AccessSizeIndex,
529 bool runOnFunction(
Function &
F)
override;
530 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
531 void maybeInsertDynamicShadowAtFunctionEntry(
Function &
F);
532 void markEscapedLocalAllocas(
Function &
F);
533 bool doInitialization(
Module &M)
override;
534 bool doFinalization(
Module &M)
override;
540 void initializeCallbacks(
Module &M);
545 uint64_t TypeSize)
const;
548 struct FunctionStateRAII {
549 AddressSanitizer *
Pass;
550 FunctionStateRAII(AddressSanitizer *
Pass) : Pass(Pass) {
551 assert(Pass->ProcessedAllocas.empty() &&
552 "last pass forgot to clear cache");
553 assert(!Pass->LocalDynamicShadow);
555 ~FunctionStateRAII() {
556 Pass->LocalDynamicShadow =
nullptr;
557 Pass->ProcessedAllocas.clear();
568 ShadowMapping Mapping;
570 Function *AsanCtorFunction =
nullptr;
571 Function *AsanInitFunction =
nullptr;
573 Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
578 Function *AsanErrorCallbackSized[2][2];
579 Function *AsanMemoryAccessCallbackSized[2][2];
580 Function *AsanMemmove, *AsanMemcpy, *AsanMemset;
582 Value *LocalDynamicShadow;
583 GlobalsMetadata GlobalsMD;
586 friend struct FunctionStackPoisoner;
589 class AddressSanitizerModule :
public ModulePass {
591 explicit AddressSanitizerModule(
bool CompileKernel =
false,
592 bool Recover =
false)
595 bool runOnModule(
Module &M)
override;
597 StringRef getPassName()
const override {
return "AddressSanitizerModule"; }
600 void initializeCallbacks(
Module &M);
620 bool ShouldUseMachOGlobalsSection()
const;
621 StringRef getGlobalMetadataSection()
const;
624 size_t MinRedzoneSizeForGlobal()
const {
625 return RedzoneSizeForScale(Mapping.Scale);
628 GlobalsMetadata GlobalsMD;
634 ShadowMapping Mapping;
640 Function *AsanUnregisterImageGlobals;
652 struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
654 AddressSanitizer &ASan;
659 ShadowMapping Mapping;
664 unsigned StackAlignment;
668 Function *AsanSetShadowFunc[0x100] = {};
669 Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc;
670 Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc;
673 struct AllocaPoisonCall {
689 AllocaForValueMapTy AllocaForValue;
691 bool HasNonEmptyInlineAsm =
false;
692 bool HasReturnsTwiceCall =
false;
693 std::unique_ptr<CallInst> EmptyInlineAsm;
695 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan)
700 IntptrTy(ASan.IntptrTy),
702 Mapping(ASan.Mapping),
703 StackAlignment(1 << Mapping.Scale),
704 EmptyInlineAsm(
CallInst::Create(ASan.EmptyAsm)) {}
706 bool runOnFunction() {
711 if (AllocaVec.empty() && DynamicAllocaVec.empty())
return false;
713 initializeCallbacks(*
F.getParent());
715 processDynamicAllocas();
716 processStaticAllocas();
727 void processStaticAllocas();
728 void processDynamicAllocas();
730 void createDynamicAllocasInitStorage();
734 void visitReturnInst(
ReturnInst &RI) { RetVec.push_back(&RI); }
737 void visitResumeInst(
ResumeInst &RI) { RetVec.push_back(&RI); }
742 void unpoisonDynamicAllocasBeforeInst(
Instruction *InstBefore,
745 Value *DynamicAreaPtr = IRB.CreatePtrToInt(SavedStack, IntptrTy);
750 if (!isa<ReturnInst>(InstBefore)) {
752 InstBefore->
getModule(), Intrinsic::get_dynamic_area_offset,
755 Value *DynamicAreaOffset = IRB.CreateCall(DynamicAreaOffsetFunc, {});
757 DynamicAreaPtr = IRB.CreateAdd(IRB.CreatePtrToInt(SavedStack, IntptrTy),
761 IRB.CreateCall(AsanAllocasUnpoisonFunc,
762 {IRB.CreateLoad(DynamicAllocaLayout), DynamicAreaPtr});
766 void unpoisonDynamicAllocas() {
767 for (
auto &
Ret : RetVec)
768 unpoisonDynamicAllocasBeforeInst(
Ret, DynamicAllocaLayout);
770 for (
auto &StackRestoreInst : StackRestoreVec)
771 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
772 StackRestoreInst->getOperand(0));
789 if (!ASan.isInterestingAlloca(AI)) {
793 if (AllocaVec.empty())
796 StaticAllocasToMoveUp.push_back(&AI);
801 StackAlignment = std::max(StackAlignment, AI.
getAlignment());
803 DynamicAllocaVec.push_back(&AI);
805 AllocaVec.push_back(&AI);
812 if (ID == Intrinsic::stackrestore) StackRestoreVec.push_back(&II);
813 if (ID == Intrinsic::localescape) LocalEscapeCall = &II;
814 if (!ASan.UseAfterScope)
816 if (ID != Intrinsic::lifetime_start && ID != Intrinsic::lifetime_end)
825 if (SizeValue == ~0ULL ||
830 if (!AI || !ASan.isInterestingAlloca(*AI))
832 bool DoPoison = (ID == Intrinsic::lifetime_end);
833 AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison};
835 StaticAllocaPoisonCallVec.push_back(APC);
837 DynamicAllocaPoisonCallVec.push_back(APC);
842 if (
CallInst *CI = dyn_cast<CallInst>(I)) {
843 HasNonEmptyInlineAsm |=
844 CI->isInlineAsm() && !CI->isIdenticalTo(EmptyInlineAsm.get());
845 HasReturnsTwiceCall |= CI->canReturnTwice();
850 void initializeCallbacks(
Module &M);
852 bool doesDominateAllExits(
const Instruction *I)
const {
853 for (
auto Ret : RetVec) {
854 if (!ASan.getDominatorTree().dominates(I,
Ret))
return false;
874 void poisonAlloca(
Value *V, uint64_t Size,
IRBuilder<> &IRB,
bool DoPoison);
886 AddressSanitizer,
"asan",
887 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false,
893 "AddressSanitizer: detects
use-after-free and out-of-bounds bugs.",
false,
897 bool UseAfterScope) {
898 assert(!CompileKernel || Recover);
899 return new AddressSanitizer(CompileKernel, Recover, UseAfterScope);
904 AddressSanitizerModule,
"asan-module",
905 "AddressSanitizer: detects use-after-free and out-of-bounds bugs."
910 assert(!CompileKernel || Recover);
911 return new AddressSanitizerModule(CompileKernel, Recover);
936 LocationMetadata MD) {
959 if (G->
getName() ==
"__llvm_gcov_ctr")
967 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
968 if (Mapping.Offset == 0)
return Shadow;
971 if (LocalDynamicShadow)
972 ShadowBase = LocalDynamicShadow;
975 if (Mapping.OrShadowOffset)
976 return IRB.
CreateOr(Shadow, ShadowBase);
978 return IRB.
CreateAdd(Shadow, ShadowBase);
984 if (isa<MemTransferInst>(MI)) {
986 isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
990 }
else if (isa<MemSetInst>(MI)) {
1001 bool AddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
1002 auto PreviouslySeenAllocaInfo = ProcessedAllocas.find(&AI);
1004 if (PreviouslySeenAllocaInfo != ProcessedAllocas.end())
1005 return PreviouslySeenAllocaInfo->getSecond();
1007 bool IsInteresting =
1020 ProcessedAllocas[&AI] = IsInteresting;
1021 return IsInteresting;
1027 unsigned *Alignment,
1028 Value **MaybeMask) {
1033 if (LocalDynamicShadow == I)
1036 Value *PtrOperand =
nullptr;
1038 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
1042 *Alignment = LI->getAlignment();
1043 PtrOperand = LI->getPointerOperand();
1044 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
1048 *Alignment =
SI->getAlignment();
1049 PtrOperand =
SI->getPointerOperand();
1050 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
1055 PtrOperand = RMW->getPointerOperand();
1061 PtrOperand = XCHG->getPointerOperand();
1062 }
else if (
auto CI = dyn_cast<CallInst>(I)) {
1064 if (
F && (
F->getName().startswith(
"llvm.masked.load.") ||
1065 F->getName().startswith(
"llvm.masked.store."))) {
1066 unsigned OpOffset = 0;
1067 if (
F->getName().startswith(
"llvm.masked.store.")) {
1080 auto Ty = cast<PointerType>(BasePtr->getType())->getElementType();
1082 if (
auto AlignmentConstant =
1083 dyn_cast<ConstantInt>(CI->
getOperand(1 + OpOffset)))
1084 *Alignment = (
unsigned)AlignmentConstant->getZExtValue();
1089 PtrOperand = BasePtr;
1112 if (
auto AI = dyn_cast_or_null<AllocaInst>(PtrOperand))
1113 return isInterestingAlloca(*AI) ? AI :
nullptr;
1126 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) {
1127 if (!Cmp->isRelational())
return false;
1129 if (BO->getOpcode() != Instruction::Sub)
return false;
1144 void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
1147 Function *
F = isa<ICmpInst>(
I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
1149 for (
Value *&
i : Param) {
1150 if (
i->getType()->isPointerTy())
1158 unsigned Alignment,
unsigned Granularity,
1160 Value *SizeArgument,
bool UseCalls,
1164 if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 ||
1166 (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8))
1167 return Pass->instrumentAddress(I, InsertBefore, Addr, TypeSize, IsWrite,
1168 nullptr, UseCalls, Exp);
1169 Pass->instrumentUnusualSizeOrAlignment(I, InsertBefore, Addr, TypeSize,
1170 IsWrite,
nullptr, UseCalls, Exp);
1176 Value *Addr,
unsigned Alignment,
1177 unsigned Granularity,
uint32_t TypeSize,
1178 bool IsWrite,
Value *SizeArgument,
1180 auto *VTy = cast<PointerType>(Addr->
getType())->getElementType();
1182 unsigned Num = VTy->getVectorNumElements();
1184 for (
unsigned Idx = 0; Idx < Num; ++Idx) {
1185 Value *InstrumentedAddress =
nullptr;
1187 if (
auto *Vector = dyn_cast<ConstantVector>(Mask)) {
1189 if (
auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
1190 if (Masked->isNullValue())
1200 InsertBefore = ThenTerm;
1204 InstrumentedAddress =
1207 Granularity, ElemTypeSize, IsWrite, SizeArgument,
1215 bool IsWrite =
false;
1216 unsigned Alignment = 0;
1217 uint64_t TypeSize = 0;
1218 Value *MaybeMask =
nullptr;
1220 isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask);
1241 isSafeAccess(ObjSizeVis, Addr, TypeSize)) {
1242 NumOptimizedAccessesToGlobalVar++;
1250 isSafeAccess(ObjSizeVis, Addr, TypeSize)) {
1251 NumOptimizedAccessesToStackVar++;
1257 NumInstrumentedWrites++;
1259 NumInstrumentedReads++;
1261 unsigned Granularity = 1 << Mapping.Scale;
1264 Alignment, Granularity, TypeSize, IsWrite,
1265 nullptr, UseCalls, Exp);
1268 IsWrite,
nullptr, UseCalls, Exp);
1273 Value *Addr,
bool IsWrite,
1274 size_t AccessSizeIndex,
1275 Value *SizeArgument,
1282 Call = IRB.
CreateCall(AsanErrorCallbackSized[IsWrite][0],
1283 {Addr, SizeArgument});
1285 Call = IRB.
CreateCall(AsanErrorCallbackSized[IsWrite][1],
1286 {Addr, SizeArgument, ExpVal});
1290 IRB.
CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
1292 Call = IRB.
CreateCall(AsanErrorCallback[IsWrite][1][AccessSizeIndex],
1306 size_t Granularity =
static_cast<size_t>(1) << Mapping.Scale;
1308 Value *LastAccessedByte =
1311 if (TypeSize / 8 > 1)
1321 void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1324 Value *SizeArgument,
bool UseCalls,
1332 IRB.
CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex],
1335 IRB.
CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1343 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1345 Value *ShadowValue =
1349 size_t Granularity = 1ULL << Mapping.Scale;
1357 assert(cast<BranchInst>(CheckTerm)->isUnconditional());
1360 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize);
1374 Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite,
1375 AccessSizeIndex, SizeArgument, Exp);
1383 void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1385 bool IsWrite,
Value *SizeArgument,
bool UseCalls,
uint32_t Exp) {
1391 IRB.
CreateCall(AsanMemoryAccessCallbackSized[IsWrite][0],
1394 IRB.
CreateCall(AsanMemoryAccessCallbackSized[IsWrite][1],
1400 instrumentAddress(I, InsertBefore, Addr, 8, IsWrite, Size,
false, Exp);
1401 instrumentAddress(I, InsertBefore, LastByte, 8, IsWrite, Size,
false, Exp);
1405 void AddressSanitizerModule::poisonOneInitializer(
Function &GlobalInit,
1413 IRB.
CreateCall(AsanPoisonGlobals, ModuleNameAddr);
1417 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
1421 void AddressSanitizerModule::createInitializerPoisonCalls(
1427 if (isa<ConstantAggregateZero>(
OP))
continue;
1436 poisonOneInitializer(*F, ModuleName);
1441 bool AddressSanitizerModule::ShouldInstrumentGlobal(
GlobalVariable *G) {
1443 DEBUG(
dbgs() <<
"GLOBAL: " << *G <<
"\n");
1445 if (GlobalsMD.get(G).IsBlacklisted)
return false;
1446 if (!Ty->
isSized())
return false;
1462 if (G->
getAlignment() > MinRedzoneSizeForGlobal())
return false;
1468 if (Section ==
"llvm.metadata")
return false;
1485 DEBUG(
dbgs() <<
"Ignoring a global initializer callback: " << *G <<
"\n");
1491 unsigned TAA = 0, StubSize = 0;
1494 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize);
1495 assert(ErrorCode.empty() &&
"Invalid section specifier.");
1500 if (ParsedSegment ==
"__OBJC" ||
1501 (ParsedSegment ==
"__DATA" && ParsedSection.
startswith(
"__objc_"))) {
1502 DEBUG(
dbgs() <<
"Ignoring ObjC runtime global: " << *G <<
"\n");
1513 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
1514 DEBUG(
dbgs() <<
"Ignoring CFString: " << *G <<
"\n");
1520 DEBUG(
dbgs() <<
"Ignoring a cstring literal: " << *G <<
"\n");
1532 bool AddressSanitizerModule::ShouldUseMachOGlobalsSection()
const {
1549 StringRef AddressSanitizerModule::getGlobalMetadataSection()
const {
1559 void AddressSanitizerModule::initializeCallbacks(
Module &M) {
1576 IntptrTy, IntptrTy,
nullptr));
1581 AsanRegisterImageGlobals =
1586 AsanUnregisterImageGlobals =
1594 void AddressSanitizerModule::SetComdatForGlobalMetadata(
1619 AddressSanitizerModule::CreateMetadataGlobal(
Module &M,
Constant *Initializer,
1624 Twine(
"__asan_global_") +
1626 Metadata->
setSection(getGlobalMetadataSection());
1640 void AddressSanitizerModule::InstrumentGlobalsCOFF(
1646 for (
size_t i = 0;
i < ExtendedGlobals.
size();
i++) {
1647 Constant *Initializer = MetadataInitializers[
i];
1650 CreateMetadataGlobal(M, Initializer, G->
getName());
1655 unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->
getType());
1657 "global metadata will not be padded appropriately");
1660 SetComdatForGlobalMetadata(G, Metadata);
1664 void AddressSanitizerModule::InstrumentGlobalsMachO(
1675 for (
size_t i = 0;
i < ExtendedGlobals.
size();
i++) {
1676 Constant *Initializer = MetadataInitializers[
i];
1679 CreateMetadataGlobal(M, Initializer, G->
getName());
1689 Liveness->
setSection(
"__DATA,__asan_liveness,regular,live_support");
1690 LivenessGlobals[
i] = Liveness;
1697 if (!LivenessGlobals.empty())
1717 IRB_Dtor.
CreateCall(AsanUnregisterImageGlobals,
1721 void AddressSanitizerModule::InstrumentGlobalsWithMetadataArray(
1725 unsigned N = ExtendedGlobals.
size();
1757 if (ShouldInstrumentGlobal(&G)) GlobalsToChange.
push_back(&G);
1760 size_t n = GlobalsToChange.
size();
1761 if (n == 0)
return false;
1777 IntptrTy, IntptrTy, IntptrTy,
nullptr);
1781 bool HasDynamicallyInitializedGlobals =
false;
1788 for (
size_t i = 0;
i < n;
i++) {
1789 static const uint64_t kMaxGlobalRedzone = 1 << 18;
1792 auto MD = GlobalsMD.get(G);
1797 M, MD.Name.
empty() ? NameForGlobal : MD.Name,
1801 uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
1802 uint64_t MinRZ = MinRedzoneSizeForGlobal();
1805 uint64_t
RZ = std::max(
1806 MinRZ,
std::min(kMaxGlobalRedzone, (SizeInBytes / MinRZ / 4) * MinRZ));
1807 uint64_t RightRedzoneSize =
RZ;
1809 if (SizeInBytes % MinRZ) RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ);
1810 assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0);
1824 "",
G, G->getThreadLocalMode());
1832 if (Seq && Seq->isCString())
1833 NewGlobal->
setSection(
"__TEXT,__asan_cstring,regular");
1839 G->getDebugInfo(GVs);
1840 for (
auto *GV : GVs)
1850 G->eraseFromParent();
1851 NewGlobals[
i] = NewGlobal;
1854 if (!MD.SourceLoc.empty()) {
1864 bool CanUsePrivateAliases =
1870 NameForGlobal + M.
getName(), NewGlobal);
1874 auto *ODRIndicatorSym =
1883 ODRIndicatorSym->setAlignment(1);
1884 ODRIndicator = ODRIndicatorSym;
1885 InstrumentedGlobal = GA;
1898 if (
ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals =
true;
1900 DEBUG(
dbgs() <<
"NEW GLOBAL: " << *NewGlobal <<
"\n");
1902 Initializers[
i] = Initializer;
1906 InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
1907 }
else if (ShouldUseMachOGlobalsSection()) {
1908 InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
1910 InstrumentGlobalsWithMetadataArray(IRB, M, NewGlobals, Initializers);
1914 if (HasDynamicallyInitializedGlobals)
1915 createInitializerPoisonCalls(M, ModuleName);
1921 bool AddressSanitizerModule::runOnModule(
Module &M) {
1926 Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
1927 initializeCallbacks(M);
1929 bool Changed =
false;
1936 Changed |= InstrumentGlobals(IRB, M);
1942 void AddressSanitizer::initializeCallbacks(
Module &M) {
1946 for (
int Exp = 0; Exp < 2; Exp++) {
1947 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
1948 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
1949 const std::string ExpStr = Exp ?
"exp_" :
"";
1950 const std::string SuffixStr = CompileKernel ?
"N" :
"_n";
1951 const std::string EndingStr = Recover ?
"_noabort" :
"";
1953 AsanErrorCallbackSized[AccessIsWrite][Exp] =
1956 IRB.
getVoidTy(), IntptrTy, IntptrTy, ExpType,
nullptr));
1957 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
1960 IRB.
getVoidTy(), IntptrTy, IntptrTy, ExpType,
nullptr));
1962 AccessSizeIndex++) {
1963 const std::string Suffix = TypeStr +
itostr(1ULL << AccessSizeIndex);
1964 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
1967 IRB.
getVoidTy(), IntptrTy, ExpType,
nullptr));
1968 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
1971 IRB.
getVoidTy(), IntptrTy, ExpType,
nullptr));
1976 const std::string MemIntrinCallbackPrefix =
1979 MemIntrinCallbackPrefix +
"memmove", IRB.
getInt8PtrTy(),
1982 MemIntrinCallbackPrefix +
"memcpy", IRB.
getInt8PtrTy(),
1985 MemIntrinCallbackPrefix +
"memset", IRB.
getInt8PtrTy(),
2002 bool AddressSanitizer::doInitialization(
Module &M) {
2012 if (!CompileKernel) {
2013 std::tie(AsanCtorFunction, AsanInitFunction) =
2019 Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
2023 bool AddressSanitizer::doFinalization(
Module &M) {
2028 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &F) {
2036 if (F.
getName().
find(
" load]") != std::string::npos) {
2044 void AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(
Function &F) {
2052 LocalDynamicShadow = IRB.
CreateLoad(GlobalDynamicAddress);
2055 void AddressSanitizer::markEscapedLocalAllocas(
Function &F) {
2060 assert(ProcessedAllocas.empty() &&
"must process localescape before allocas");
2075 "non-static alloca arg to localescape");
2076 ProcessedAllocas[AI] =
false;
2083 bool AddressSanitizer::runOnFunction(
Function &F) {
2084 if (&F == AsanCtorFunction)
return false;
2089 bool FunctionModified =
false;
2094 if (maybeInsertAsanInitAtFunctionEntry(F))
2095 FunctionModified =
true;
2098 if (!F.
hasFnAttribute(Attribute::SanitizeAddress))
return FunctionModified;
2100 DEBUG(
dbgs() <<
"ASAN instrumenting:\n" << F <<
"\n");
2103 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
2105 FunctionStateRAII CleanupObj(
this);
2107 maybeInsertDynamicShadowAtFunctionEntry(F);
2111 markEscapedLocalAllocas(F);
2125 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
2128 for (
auto &BB : F) {
2130 TempsToInstrument.
clear();
2131 int NumInsnsPerBB = 0;
2132 for (
auto &Inst : BB) {
2133 if (LooksLikeCodeInBug11395(&Inst))
return false;
2134 Value *MaybeMask =
nullptr;
2135 if (
Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
2136 &Alignment, &MaybeMask)) {
2142 if (TempsToInstrument.
count(Addr))
2145 if (!TempsToInstrument.
insert(Addr).second)
2151 PointerComparisonsOrSubtracts.
push_back(&Inst);
2153 }
else if (isa<MemIntrinsic>(Inst)) {
2156 if (isa<AllocaInst>(Inst)) NumAllocas++;
2160 TempsToInstrument.
clear();
2161 if (CS.doesNotReturn()) NoReturnCalls.
push_back(CS.getInstruction());
2163 if (
CallInst *CI = dyn_cast<CallInst>(&Inst))
2177 const DataLayout &DL = F.getParent()->getDataLayout();
2182 int NumInstrumented = 0;
2183 for (
auto Inst : ToInstrument) {
2186 if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
2187 instrumentMop(ObjSizeVis, Inst, UseCalls,
2188 F.getParent()->getDataLayout());
2190 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
2195 FunctionStackPoisoner FSP(F, *
this);
2196 bool ChangedStack = FSP.runOnFunction();
2200 for (
auto CI : NoReturnCalls) {
2205 for (
auto Inst : PointerComparisonsOrSubtracts) {
2206 instrumentPointerComparisonOrSubtraction(Inst);
2210 if (NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty())
2211 FunctionModified =
true;
2213 DEBUG(
dbgs() <<
"ASAN done instrumenting: " << FunctionModified <<
" "
2216 return FunctionModified;
2222 bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *I) {
2223 if (LongSize != 32)
return false;
2231 void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
2234 std::string Suffix =
itostr(
i);
2237 IntptrTy,
nullptr));
2240 IRB.
getVoidTy(), IntptrTy, IntptrTy,
nullptr));
2242 if (ASan.UseAfterScope) {
2245 IntptrTy, IntptrTy,
nullptr));
2248 IntptrTy, IntptrTy,
nullptr));
2251 for (
size_t Val : {0x00, 0xf1, 0xf2, 0xf3, 0xf5, 0xf8}) {
2252 std::ostringstream
Name;
2254 Name << std::setw(2) << std::setfill(
'0') << std::hex << Val;
2255 AsanSetShadowFunc[Val] =
2257 Name.str(), IRB.
getVoidTy(), IntptrTy, IntptrTy,
nullptr));
2262 AsanAllocasUnpoisonFunc =
2269 size_t Begin,
size_t End,
2271 Value *ShadowBase) {
2275 const size_t LargestStoreSizeInBytes =
2276 std::min<size_t>(
sizeof(uint64_t), ASan.LongSize / 8);
2278 const bool IsLittleEndian = F.getParent()->getDataLayout().isLittleEndian();
2284 for (
size_t i = Begin;
i <
End;) {
2285 if (!ShadowMask[
i]) {
2291 size_t StoreSizeInBytes = LargestStoreSizeInBytes;
2293 while (StoreSizeInBytes > End - i)
2294 StoreSizeInBytes /= 2;
2297 for (
size_t j = StoreSizeInBytes - 1; j && !ShadowMask[i + j]; --j) {
2298 while (j <= StoreSizeInBytes / 2)
2299 StoreSizeInBytes /= 2;
2303 for (
size_t j = 0; j < StoreSizeInBytes; j++) {
2305 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
2307 Val = (Val << 8) | ShadowBytes[i + j];
2311 Value *Poison = IRB.
getIntN(StoreSizeInBytes * 8, Val);
2315 i += StoreSizeInBytes;
2322 copyToShadow(ShadowMask, ShadowBytes, 0, ShadowMask.
size(), IRB, ShadowBase);
2327 size_t Begin,
size_t End,
2330 size_t Done = Begin;
2331 for (
size_t i = Begin, j = Begin + 1; i <
End; i = j++) {
2332 if (!ShadowMask[i]) {
2336 uint8_t Val = ShadowBytes[
i];
2337 if (!AsanSetShadowFunc[Val])
2341 for (; j < End && ShadowMask[j] && Val == ShadowBytes[j]; ++j) {
2345 copyToShadowInline(ShadowMask, ShadowBytes, Done, i, IRB, ShadowBase);
2353 copyToShadowInline(ShadowMask, ShadowBytes, Done, End, IRB, ShadowBase);
2361 for (
int i = 0;; i++, MaxSize *= 2)
2362 if (LocalStackSize <= MaxSize)
return i;
2369 Value *ValueIfFalse) {
2378 Value *FunctionStackPoisoner::createAllocaForLayout(
2387 nullptr,
"MyAlloca");
2396 void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
2399 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
2404 void FunctionStackPoisoner::processDynamicAllocas() {
2406 assert(DynamicAllocaPoisonCallVec.empty());
2411 for (
const auto &APC : DynamicAllocaPoisonCallVec) {
2414 assert(ASan.isInterestingAlloca(*APC.AI));
2415 assert(!APC.AI->isStaticAlloca());
2418 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
2425 createDynamicAllocasInitStorage();
2426 for (
auto &AI : DynamicAllocaVec)
2427 handleDynamicAllocaCall(AI);
2428 unpoisonDynamicAllocas();
2431 void FunctionStackPoisoner::processStaticAllocas() {
2432 if (AllocaVec.empty()) {
2433 assert(StaticAllocaPoisonCallVec.empty());
2437 int StackMallocIdx = -1;
2439 if (
auto SP = F.getSubprogram())
2449 auto InsBeforeB = InsBefore->
getParent();
2450 assert(InsBeforeB == &F.getEntryBlock());
2451 for (
auto *AI : StaticAllocasToMoveUp)
2456 if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore);
2459 SVD.
reserve(AllocaVec.size());
2462 ASan.getAllocaSizeInBytes(*AI),
2473 size_t MinHeaderSize = ASan.LongSize / 2;
2479 for (
auto &
Desc : SVD)
2483 for (
const auto &APC : StaticAllocaPoisonCallVec) {
2486 assert(ASan.isInterestingAlloca(*APC.AI));
2487 assert(APC.AI->isStaticAlloca());
2490 Desc.LifetimeSize = Desc.Size;
2492 if (
const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
2493 if (LifetimeLoc->getFile() == FnLoc->getFile())
2494 if (
unsigned Line = LifetimeLoc->getLine())
2495 Desc.Line =
std::min(Desc.Line ? Desc.Line : Line, Line);
2512 DoDynamicAlloca &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall;
2513 DoStackMalloc &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall;
2515 Value *StaticAlloca =
2516 DoDynamicAlloca ?
nullptr : createAllocaForLayout(IRB, L,
false);
2519 Value *LocalStackBase;
2521 if (DoStackMalloc) {
2526 Constant *OptionDetectUseAfterReturn = F.getParent()->getOrInsertGlobal(
2528 Value *UseAfterReturnIsEnabled =
2534 IRBIf.SetCurrentDebugLocation(EntryDebugLocation);
2537 Value *FakeStackValue =
2538 IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx],
2542 FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term,
2545 Value *NoFakeStack =
2548 IRBIf.SetInsertPoint(Term);
2549 IRBIf.SetCurrentDebugLocation(EntryDebugLocation);
2550 Value *AllocaValue =
2551 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
2554 LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack);
2560 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
2564 for (
const auto &Desc : SVD) {
2598 Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB);
2601 copyToShadow(ShadowAfterScope, ShadowAfterScope, IRB, ShadowBase);
2603 if (!StaticAllocaPoisonCallVec.empty()) {
2607 for (
const auto &APC : StaticAllocaPoisonCallVec) {
2614 copyToShadow(ShadowAfterScope,
2615 APC.DoPoison ? ShadowAfterScope : ShadowInScope, Begin, End,
2624 for (
auto Ret : RetVec) {
2629 if (DoStackMalloc) {
2630 assert(StackMallocIdx >= 0);
2647 if (StackMallocIdx <= 4) {
2651 copyToShadow(ShadowAfterReturn, ShadowAfterReturn, IRBPoison,
2653 Value *SavedFlagPtrPtr = IRBPoison.CreateAdd(
2656 Value *SavedFlagPtr = IRBPoison.CreateLoad(
2657 IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy));
2658 IRBPoison.CreateStore(
2660 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy()));
2663 IRBPoison.CreateCall(
2664 AsanStackFreeFunc[StackMallocIdx],
2669 copyToShadow(ShadowAfterScope, ShadowClean, IRBElse, ShadowBase);
2671 copyToShadow(ShadowAfterScope, ShadowClean, IRBRet, ShadowBase);
2679 void FunctionStackPoisoner::poisonAlloca(
Value *V, uint64_t Size,
2685 DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
2686 {AddrArg, SizeArg});
2699 if (
AllocaInst *AI = dyn_cast<AllocaInst>(V))
2701 return ASan.isInterestingAlloca(*AI) ? AI :
nullptr;
2704 AllocaForValueMapTy::iterator I = AllocaForValue.find(V);
2705 if (I != AllocaForValue.end())
return I->second;
2708 AllocaForValue[V] =
nullptr;
2712 else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
2713 for (
Value *IncValue : PN->incoming_values()) {
2715 if (IncValue == PN)
continue;
2716 AllocaInst *IncValueAI = findAllocaForValue(IncValue);
2718 if (IncValueAI ==
nullptr || (Res !=
nullptr && IncValueAI != Res))
2723 Res = findAllocaForValue(EP->getPointerOperand());
2725 DEBUG(
dbgs() <<
"Alloca search canceled on unknown instruction: " << *V <<
"\n");
2727 if (Res) AllocaForValue[V] = Res;
2731 void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
2745 const unsigned ElementSize =
2778 IRB.
CreateCall(AsanAllocaPoisonFunc, {NewAddress, OldSize});
2797 Value *Addr, uint64_t TypeSize)
const {
2799 if (!ObjSizeVis.
bothKnown(SizeOffset))
return false;
2800 uint64_t Size = SizeOffset.first.getZExtValue();
2801 int64_t
Offset = SizeOffset.second.getSExtValue();
2806 return Offset >= 0 && Size >= uint64_t(Offset) &&
2807 Size - uint64_t(Offset) >= TypeSize / 8;
void setVisibility(VisibilityTypes V)
Pass interface - Implemented by all 'passes'.
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...
Return a value (possibly void), from a function.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static const char *const kAsanSetShadowPrefix
void push_back(const T &Elt)
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. ...
LinkageTypes getLinkage() const
bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, bool Deref, int Offset=0)
Replaces llvm.dbg.declare instruction when the alloca it describes is replaced with a new value...
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
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))
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...
VisibilityTypes getVisibility() const
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G)
Check if G has been created by a trusted compiler pass.
void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, TerminatorInst **ThenTerm, TerminatorInst **ElseTerm, MDNode *BranchWeights=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
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))
Function * checkSanitizerInterfaceFunction(Constant *FuncOrBitcast)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
STATISTIC(NumFunctions,"Total number of functions")
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
A Module instance is used to store all the information related to an LLVM module. ...
void setAlignment(unsigned Align)
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
aarch64 AArch64 CCMP Pass
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Available for inspection, not emission.
unsigned getNumOperands() const
Return number of MDNode operands.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
bool isMacOSXVersionLT(unsigned Major, unsigned Minor=0, unsigned Micro=0) const
isMacOSXVersionLT - Comparison function for checking OS X version compatibility, which handles suppor...
Type * getValueType() const
static const uintptr_t kCurrentStackFrameMagic
This class represents a function call, abstracting a target machine's calling convention.
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 * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static cl::opt< bool > ClUseMachOGlobalsSection("asan-globals-live-support", cl::desc("Use linker features to support dead ""code stripping of globals ""(Mach-O only)"), cl::Hidden, cl::init(true))
Like Internal, but omit from symbol table.
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))
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
If this value is smaller than the specified limit, return it, otherwise return the limit value...
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))
const Function * getParent() const
Return the enclosing method, or null if none.
SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
const Instruction & front() const
static cl::opt< bool > ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false))
An instruction for reading from memory.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
static cl::opt< bool > ClUsePrivateAliasForGlobals("asan-use-private-alias", cl::desc("Use private aliases for global"" variables"), cl::Hidden, cl::init(false))
void reserve(size_type N)
void setAlignment(unsigned Align)
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
static GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging)
static cl::opt< unsigned long long > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
bool isAndroid() const
Tests whether the target is Android.
bool isOSWindows() const
Tests whether the OS is Windows.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
StringRef getName() const
Return a constant reference to the value's name.
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.
bool isArrayAllocation() const
Return true if there is an allocation size parameter to the allocation instruction that is not 1...
static const uint64_t kDefaultShadowScale
bool isMacOSX() const
isMacOSX - Is this a Mac OS X triple.
static const char *const kAsanShadowMemoryDynamicAddress
AllocaInst * CreateAlloca(Type *Ty, Value *ArraySize=nullptr, const Twine &Name="")
static const int kAsanStackUseAfterReturnMagic
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
DILocation * get() const
Get the underlying DILocation.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
StringRef getName() const
Get a short "name" for the module.
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
This is the base class for all instructions that perform data casts.
const APInt & getValue() const
Return the constant as an APInt value reference.
Class to represent struct types.
static const uint64_t kLinuxKasan_ShadowOffset64
A Use represents the edge between a Value definition and its users.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
unsigned getNumArgOperands() const
Return the number of call arguments.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static const char *const kAsanAllocasUnpoison
ObjectFormatType getObjectFormat() const
getFormat - Get the object format for this triple.
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
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
static const uint64_t kIOSSimShadowOffset64
Type * getVoidTy()
Fetch the type representing void.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
bool isOSLinux() const
Tests whether the OS is Linux.
static const char *const kAsanPoisonStackMemoryName
static const uint64_t kSmallX86_64ShadowOffset
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
ConstantDataSequential - A vector or array constant whose element type is a simple 1/2/4/8-byte integ...
static const char *const kSanCovGenPrefix
unsigned getAlignment() const
Class to represent array types.
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))
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
getLimitedValue - If the value is smaller than the specified limit, return it, otherwise return the l...
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)
StringRef getSection() const
Get the custom section of this global if it has one.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static cl::opt< bool > ClOpt("asan-opt", cl::desc("Optimize instrumentation"), cl::Hidden, cl::init(true))
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static const uint64_t kWindowsShadowOffset64
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
An instruction for storing to memory.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
std::pair< APInt, APInt > SizeOffsetType
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()
Type * getScalarType() const LLVM_READONLY
If this is a vector type, return the element type, otherwise return 'this'.
size_t size() const
size - Get the array size.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
static const uint64_t kDefaultShadowOffset32
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
Class to represent pointers.
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)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
ModulePass * createAddressSanitizerModulePass(bool CompileKernel=false, bool Recover=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
bool hasSection() const
Check if this global has a custom object file section.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
bool isiOS() const
Is this an iOS triple.
LoadInst * CreateLoad(Value *Ptr, const char *Name)
static const size_t kNumberOfAccessSizes
static const char *const kAsanGlobalsRegisteredFlagName
initializer< Ty > init(const Ty &Val)
No other Module may specify this COMDAT.
static const char *const kAsanPtrCmp
static std::string ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
Parse the section specifier indicated by "Spec".
Subclasses of this class are all able to terminate a basic block.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
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...
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.
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
This is an important class for using LLVM in a threaded context.
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
Constant * getOrInsertGlobal(StringRef Name, Type *Ty)
Look up the specified global in the module symbol table.
Conditional or Unconditional Branch instruction.
static const size_t kMinStackMallocSize
This function has undefined behavior.
const Comdat * getComdat() const
This is an important base class in LLVM.
PointerType * getType() const
Overload to return most specific pointer type.
Resume the propagation of an exception.
static const char *const kAsanInitName
static const char *const kAsanStackFreeNameTemplate
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
static const uint64_t kMIPS32_ShadowOffset32
static const char *const kAsanOptionDetectUseAfterReturn
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
static const uint64_t kFreeBSD_ShadowOffset32
static const uint64_t kAArch64_ShadowOffset64
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
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.
static Type * getVoidTy(LLVMContext &C)
bool isWatchOS() const
Is this an Apple watchOS triple.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
This instruction compares its operands according to the predicate given to the constructor.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
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)
static cl::opt< bool > ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true))
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
static const uintptr_t kRetiredStackFrameMagic
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static const char *const kAsanGenPrefix
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
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.
bool isPointerTy() const
True if this is an instance of PointerType.
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
static std::string itostr(int64_t X)
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
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...
#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)
Triple - Helper class for working with autoconf configuration names.
static const char *const kAsanRegisterGlobalsName
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
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.
StringRef getString() const
static const uint64_t kDynamicShadowSentinel
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
const MDOperand & getOperand(unsigned I) const
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
This is the common base class for memset/memcpy/memmove.
const BasicBlockListType & getBasicBlockList() const
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
This is the shared class of boolean and integer constants.
void setSelectionKind(SelectionKind Val)
static const char *const kAsanStackMallocNameTemplate
InstrTy * getInstruction() const
static const char *const kAsanUnpoisonStackMemoryName
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
INITIALIZE_PASS(AddressSanitizerModule,"asan-module","AddressSanitizer: detects use-after-free and out-of-bounds bugs.""ModulePass", false, false) ModulePass *llvm
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Evaluate the size and offset of an object pointed to by a Value* statically.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > Bundles=None, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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)
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
INITIALIZE_PASS_BEGIN(AddressSanitizer,"asan","AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) INITIALIZE_PASS_END(AddressSanitizer
TerminatorInst * 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 ...
static const uint64_t kDefaultShadowOffset64
bool isSwiftError() const
Return true if this value is a swifterror value.
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 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)
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.
const BasicBlock & getEntryBlock() const
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 GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
SizeOffsetType compute(Value *V)
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
Value * CreateGEP(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
ConstantArray - Constant Array Declarations.
bool hasInitializer() const
Definitions have initializers, declarations don't.
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.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
bool isInlineAsm() const
Check if this call is an inline asm statement.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
bool isOSVersionLT(unsigned Major, unsigned Minor=0, unsigned Micro=0) const
isOSVersionLT - Helper function for doing comparisons against version numbers included in the target ...
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
ThreadLocalMode getThreadLocalMode() const
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
static const uint64_t kMIPS64_ShadowOffset64
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void setUnnamedAddr(UnnamedAddr Val)
static IntegerType * getInt32Ty(LLVMContext &C)
static int StackMallocSizeClass(uint64_t LocalStackSize)
static cl::opt< uint32_t > ClForceExperiment("asan-force-experiment", cl::desc("Force optimization experiment (for testing)"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClDynamicAllocaStack("asan-stack-dynamic-alloca", cl::desc("Use dynamic alloca to represent stack variables"), cl::Hidden, cl::init(true))
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
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)
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...
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 char *const kAsanModuleDtorName
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
bool hasLocalLinkage() const
static const char *const kAsanUnregisterGlobalsName
iterator_range< df_iterator< T > > depth_first(const T &G)
static const char *const kAsanUnpoisonGlobalsName
void copyAttributesFrom(const GlobalValue *Src) override
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
iterator_range< op_iterator > arg_operands()
Iteration adapter for range-for loops.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool bothKnown(const SizeOffsetType &SizeOffset)
const BasicBlock & front() const
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)
static const char *const kAsanVersionCheckName
static const uint64_t kPPC64_ShadowOffset64
static const unsigned kAllocaRzSize
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
const Value * getArraySize() const
Get the number of elements allocated.
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 ...
static const char *const kAsanRegisterImageGlobalsName
DLLStorageClassTypes getDLLStorageClass() const
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
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).
void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
FunctionPass * createAddressSanitizerFunctionPass(bool CompileKernel=false, bool Recover=false, bool UseAfterScope=false)
static const char *const kAsanAllocaPoison
static const char *const kAsanHandleNoReturnName
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
iterator_range< global_iterator > globals()
static const size_t kMaxStackMallocSize
StringRef - Represent a constant reference to a string, i.e.
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))
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
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))
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
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))
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
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.
const BasicBlock * getParent() const
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 isOne() const
This is just a convenience method to make client code smaller for a common case.
GlobalVariable * getGlobalVariable(StringRef Name) const
Look up the specified global variable in the module symbol table.
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))
A wrapper class for inspecting calls to intrinsic functions.
LLVMContext & getContext() const
Get the global data context.
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