45 #include "llvm/Support/DataTypes.h"
59 #include <system_error>
63 #define DEBUG_TYPE "asan"
90 "__asan_unregister_globals";
103 "__asan_poison_stack_memory";
105 "__asan_unpoison_stack_memory";
108 "__asan_option_detect_stack_use_after_return";
120 "asan-kernel",
cl::desc(
"Enable KernelAddressSanitizer instrumentation"),
125 cl::desc(
"instrument read instructions"),
128 "asan-instrument-writes",
cl::desc(
"instrument write instructions"),
131 "asan-instrument-atomics",
135 "asan-always-slow-path",
143 "asan-max-ins-per-bb",
cl::init(10000),
144 cl::desc(
"maximal number of instructions to instrument in any given BB"),
150 cl::desc(
"Check return-after-free"),
157 cl::desc(
"Handle C++ initializer order"),
160 "asan-detect-invalid-pointer-pair",
164 "asan-realign-stack",
165 cl::desc(
"Realign stack to the value of this flag (power of two)"),
168 "asan-instrumentation-with-call-threshold",
170 "If the function being instrumented contains more than "
171 "this number of memory accesses, use callbacks instead of "
172 "inline checks (-1 means never use callbacks)."),
175 "asan-memory-access-callback-prefix",
179 cl::desc(
"instrument dynamic allocas"),
182 "asan-skip-promotable-allocas",
190 cl::desc(
"scale of asan shadow mapping"),
198 "asan-opt-same-temp",
cl::desc(
"Instrument the same temp just once"),
201 cl::desc(
"Don't instrument scalar globals"),
204 "asan-opt-stack",
cl::desc(
"Don't instrument scalar stack variables"),
208 "asan-check-lifetime",
213 "asan-stack-dynamic-alloca",
218 "asan-force-experiment",
234 STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
235 STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
236 STATISTIC(NumOptimizedAccessesToGlobalVar,
237 "Number of optimized accesses to global vars");
238 STATISTIC(NumOptimizedAccessesToStackVar,
239 "Number of optimized accesses to stack vars");
243 struct LocationMetadata {
248 LocationMetadata() : Filename(), LineNo(0), ColumnNo(0) {}
250 bool empty()
const {
return Filename.empty(); }
257 mdconst::extract<ConstantInt>(MDN->
getOperand(1))->getLimitedValue();
259 mdconst::extract<ConstantInt>(MDN->
getOperand(2))->getLimitedValue();
264 class GlobalsMetadata {
267 Entry() : SourceLoc(),
Name(), IsDynInit(
false), IsBlacklisted(
false) {}
268 LocationMetadata SourceLoc;
274 GlobalsMetadata() : inited_(
false) {}
280 if (!Globals)
return;
281 for (
auto MDN : Globals->
operands()) {
284 auto *GV = mdconst::extract_or_null<GlobalVariable>(MDN->
getOperand(0));
289 Entry &E = Entries[GV];
290 if (
auto *Loc = cast_or_null<MDNode>(MDN->
getOperand(1)))
291 E.SourceLoc.parse(Loc);
293 E.Name =
Name->getString();
295 mdconst::extract<ConstantInt>(MDN->
getOperand(3));
296 E.IsDynInit |= IsDynInit->
isOne();
298 mdconst::extract<ConstantInt>(MDN->
getOperand(4));
299 E.IsBlacklisted |= IsBlacklisted->
isOne();
305 auto Pos = Entries.find(
G);
306 return (Pos != Entries.end()) ? Pos->second : Entry();
316 struct ShadowMapping {
322 static ShadowMapping getShadowMapping(
Triple &TargetTriple,
int LongSize,
325 bool IsIOS = TargetTriple.
isiOS();
338 ShadowMapping Mapping;
340 if (LongSize == 32) {
358 else if (IsLinux && IsX86_64) {
379 Mapping.OrShadowOffset = !IsPPC64 && !(Mapping.Offset & (Mapping.Offset - 1));
384 static size_t RedzoneSizeForScale(
int MappingScale) {
387 return std::max(32U, 1U << MappingScale);
392 explicit AddressSanitizer(
bool CompileKernel =
false)
396 const char *getPassName()
const override {
397 return "AddressSanitizerFunctionPass";
403 uint64_t getAllocaSizeInBytes(
AllocaInst *AI)
const {
405 uint64_t SizeInBytes =
420 uint64_t *TypeSize,
unsigned *Alignment);
423 void instrumentPointerComparisonOrSubtraction(
Instruction *
I);
425 Value *Addr, uint32_t TypeSize,
bool IsWrite,
426 Value *SizeArgument,
bool UseCalls, uint32_t Exp);
428 uint32_t TypeSize,
bool IsWrite,
429 Value *SizeArgument,
bool UseCalls,
432 Value *ShadowValue, uint32_t TypeSize);
434 bool IsWrite,
size_t AccessSizeIndex,
435 Value *SizeArgument, uint32_t Exp);
438 bool runOnFunction(
Function &
F)
override;
439 bool maybeInsertAsanInitAtFunctionEntry(
Function &
F);
440 bool doInitialization(
Module &M)
override;
446 void initializeCallbacks(
Module &M);
451 uint64_t TypeSize)
const;
458 ShadowMapping Mapping;
460 Function *AsanCtorFunction =
nullptr;
461 Function *AsanInitFunction =
nullptr;
463 Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
468 Function *AsanErrorCallbackSized[2][2];
469 Function *AsanMemoryAccessCallbackSized[2][2];
470 Function *AsanMemmove, *AsanMemcpy, *AsanMemset;
472 GlobalsMetadata GlobalsMD;
475 friend struct FunctionStackPoisoner;
478 class AddressSanitizerModule :
public ModulePass {
480 explicit AddressSanitizerModule(
bool CompileKernel =
false)
482 bool runOnModule(
Module &M)
override;
484 const char *getPassName()
const override {
return "AddressSanitizerModule"; }
487 void initializeCallbacks(
Module &M);
493 size_t MinRedzoneSizeForGlobal()
const {
494 return RedzoneSizeForScale(Mapping.Scale);
497 GlobalsMetadata GlobalsMD;
502 ShadowMapping Mapping;
518 struct FunctionStackPoisoner :
public InstVisitor<FunctionStackPoisoner> {
520 AddressSanitizer &ASan;
525 ShadowMapping Mapping;
529 unsigned StackAlignment;
533 Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc;
534 Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc;
537 struct AllocaPoisonCall {
551 AllocaForValueMapTy AllocaForValue;
553 bool HasNonEmptyInlineAsm;
554 std::unique_ptr<CallInst> EmptyInlineAsm;
556 FunctionStackPoisoner(
Function &
F, AddressSanitizer &ASan)
561 IntptrTy(ASan.IntptrTy),
563 Mapping(ASan.Mapping),
564 StackAlignment(1 << Mapping.Scale),
565 HasNonEmptyInlineAsm(
false),
566 EmptyInlineAsm(
CallInst::Create(ASan.EmptyAsm)) {}
568 bool runOnFunction() {
573 if (AllocaVec.empty() && DynamicAllocaVec.empty())
return false;
575 initializeCallbacks(*
F.getParent());
590 void createDynamicAllocasInitStorage();
594 void visitReturnInst(
ReturnInst &RI) { RetVec.push_back(&RI); }
596 void unpoisonDynamicAllocasBeforeInst(
Instruction *InstBefore,
599 IRB.CreateCall(AsanAllocasUnpoisonFunc,
600 {IRB.CreateLoad(DynamicAllocaLayout),
601 IRB.CreatePtrToInt(SavedStack, IntptrTy)});
605 void unpoisonDynamicAllocas() {
606 for (
auto &
Ret : RetVec)
607 unpoisonDynamicAllocasBeforeInst(
Ret, DynamicAllocaLayout);
609 for (
auto &StackRestoreInst : StackRestoreVec)
610 unpoisonDynamicAllocasBeforeInst(StackRestoreInst,
611 StackRestoreInst->getOperand(0));
628 if (!ASan.isInterestingAlloca(AI))
return;
630 StackAlignment = std::max(StackAlignment, AI.
getAlignment());
631 if (ASan.isDynamicAlloca(AI))
632 DynamicAllocaVec.push_back(&AI);
634 AllocaVec.push_back(&AI);
641 if (ID == Intrinsic::stackrestore) StackRestoreVec.push_back(&II);
643 if (ID != Intrinsic::lifetime_start && ID != Intrinsic::lifetime_end)
652 if (SizeValue == ~0ULL ||
658 bool DoPoison = (ID == Intrinsic::lifetime_end);
659 AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison};
660 AllocaPoisonCallVec.push_back(APC);
664 HasNonEmptyInlineAsm |=
669 void initializeCallbacks(
Module &M);
672 for (
auto Ret : RetVec) {
673 if (!ASan.getDominatorTree().dominates(I,
Ret))
return false;
681 Value *ShadowBase,
bool DoPoison);
682 void poisonAlloca(
Value *V, uint64_t Size,
IRBuilder<> &IRB,
bool DoPoison);
684 void SetShadowToStackAfterReturnInlined(
IRBuilder<> &IRB,
Value *ShadowBase,
696 AddressSanitizer,
"asan",
697 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false,
702 "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false,
705 return new AddressSanitizer(CompileKernel);
710 AddressSanitizerModule,
"asan-module",
711 "AddressSanitizer: detects use-after-free and out-of-bounds bugs."
715 return new AddressSanitizerModule(CompileKernel);
740 LocationMetadata MD) {
761 Shadow = IRB.
CreateLShr(Shadow, Mapping.Scale);
762 if (Mapping.Offset == 0)
return Shadow;
764 if (Mapping.OrShadowOffset)
773 if (isa<MemTransferInst>(MI)) {
775 isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
779 }
else if (isa<MemSetInst>(MI)) {
790 bool AddressSanitizer::isInterestingAlloca(
AllocaInst &AI) {
791 auto PreviouslySeenAllocaInfo = ProcessedAllocas.find(&AI);
793 if (PreviouslySeenAllocaInfo != ProcessedAllocas.end())
794 return PreviouslySeenAllocaInfo->getSecond();
799 getAllocaSizeInBytes(&AI) > 0 &&
803 isDynamicAlloca(AI)));
805 ProcessedAllocas[&AI] = IsInteresting;
806 return IsInteresting;
814 unsigned *Alignment) {
818 Value *PtrOperand =
nullptr;
820 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
824 *Alignment = LI->getAlignment();
825 PtrOperand = LI->getPointerOperand();
826 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
830 *Alignment =
SI->getAlignment();
831 PtrOperand =
SI->getPointerOperand();
832 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
837 PtrOperand = RMW->getPointerOperand();
843 PtrOperand = XCHG->getPointerOperand();
850 if (
auto AI = dyn_cast_or_null<AllocaInst>(PtrOperand))
851 return isInterestingAlloca(*AI) ? AI :
nullptr;
864 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(I)) {
865 if (!Cmp->isRelational())
return false;
867 if (BO->getOpcode() != Instruction::Sub)
return false;
884 void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
887 Function *
F = isa<ICmpInst>(
I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
889 for (
int i = 0; i < 2; i++) {
890 if (Param[i]->
getType()->isPointerTy())
899 bool IsWrite =
false;
900 unsigned Alignment = 0;
901 uint64_t TypeSize = 0;
902 Value *Addr = isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment);
922 if (G != NULL && (!
ClInitializers || GlobalIsLinkerInitialized(G)) &&
923 isSafeAccess(ObjSizeVis, Addr, TypeSize)) {
924 NumOptimizedAccessesToGlobalVar++;
932 isSafeAccess(ObjSizeVis, Addr, TypeSize)) {
933 NumOptimizedAccessesToStackVar++;
939 NumInstrumentedWrites++;
941 NumInstrumentedReads++;
943 unsigned Granularity = 1 << Mapping.Scale;
946 if ((TypeSize == 8 || TypeSize == 16 || TypeSize == 32 || TypeSize == 64 ||
948 (Alignment >= Granularity || Alignment == 0 || Alignment >= TypeSize / 8))
949 return instrumentAddress(I, I, Addr, TypeSize, IsWrite,
nullptr, UseCalls,
951 instrumentUnusualSizeOrAlignment(I, Addr, TypeSize, IsWrite,
nullptr,
956 Value *Addr,
bool IsWrite,
957 size_t AccessSizeIndex,
965 Call = IRB.
CreateCall(AsanErrorCallbackSized[IsWrite][0],
966 {Addr, SizeArgument});
968 Call = IRB.
CreateCall(AsanErrorCallbackSized[IsWrite][1],
969 {Addr, SizeArgument, ExpVal});
973 IRB.
CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr);
975 Call = IRB.
CreateCall(AsanErrorCallback[IsWrite][1][AccessSizeIndex],
989 size_t Granularity = 1 << Mapping.Scale;
991 Value *LastAccessedByte =
994 if (TypeSize / 8 > 1)
1004 void AddressSanitizer::instrumentAddress(
Instruction *OrigIns,
1006 uint32_t TypeSize,
bool IsWrite,
1007 Value *SizeArgument,
bool UseCalls,
1015 IRB.
CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex],
1018 IRB.
CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex],
1026 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1028 Value *ShadowValue =
1032 size_t Granularity = 1 << Mapping.Scale;
1040 assert(cast<BranchInst>(CheckTerm)->isUnconditional());
1043 Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize);
1053 Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite,
1054 AccessSizeIndex, SizeArgument, Exp);
1062 void AddressSanitizer::instrumentUnusualSizeOrAlignment(
1064 Value *SizeArgument,
bool UseCalls, uint32_t Exp) {
1070 IRB.
CreateCall(AsanMemoryAccessCallbackSized[IsWrite][0],
1073 IRB.
CreateCall(AsanMemoryAccessCallbackSized[IsWrite][1],
1079 instrumentAddress(I, I, Addr, 8, IsWrite, Size,
false, Exp);
1080 instrumentAddress(I, I, LastByte, 8, IsWrite, Size,
false, Exp);
1084 void AddressSanitizerModule::poisonOneInitializer(
Function &GlobalInit,
1091 IRB.
CreateCall(AsanPoisonGlobals, ModuleNameAddr);
1095 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
1099 void AddressSanitizerModule::createInitializerPoisonCalls(
1105 if (isa<ConstantAggregateZero>(
OP))
continue;
1114 poisonOneInitializer(*F, ModuleName);
1119 bool AddressSanitizerModule::ShouldInstrumentGlobal(
GlobalVariable *G) {
1120 Type *Ty = cast<PointerType>(G->
getType())->getElementType();
1121 DEBUG(
dbgs() <<
"GLOBAL: " << *G <<
"\n");
1123 if (GlobalsMD.get(G).IsBlacklisted)
return false;
1124 if (!Ty->
isSized())
return false;
1140 if (G->
getAlignment() > MinRedzoneSizeForGlobal())
return false;
1146 if (
Section ==
"llvm.metadata")
return false;
1154 if (
Section.startswith(
".CRT")) {
1155 DEBUG(
dbgs() <<
"Ignoring a global initializer callback: " << *G <<
"\n");
1161 unsigned TAA = 0, StubSize = 0;
1164 Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize);
1165 if (!ErrorCode.empty()) {
1166 assert(
false &&
"Invalid section specifier.");
1173 if (ParsedSegment ==
"__OBJC" ||
1174 (ParsedSegment ==
"__DATA" && ParsedSection.
startswith(
"__objc_"))) {
1175 DEBUG(
dbgs() <<
"Ignoring ObjC runtime global: " << *G <<
"\n");
1186 if (ParsedSegment ==
"__DATA" && ParsedSection ==
"__cfstring") {
1187 DEBUG(
dbgs() <<
"Ignoring CFString: " << *G <<
"\n");
1193 DEBUG(
dbgs() <<
"Ignoring a cstring literal: " << *G <<
"\n");
1202 void AddressSanitizerModule::initializeCallbacks(
Module &M) {
1217 IntptrTy, IntptrTy,
nullptr));
1230 if (ShouldInstrumentGlobal(&G)) GlobalsToChange.
push_back(&G);
1233 size_t n = GlobalsToChange.
size();
1234 if (n == 0)
return false;
1247 IntptrTy, IntptrTy,
nullptr);
1250 bool HasDynamicallyInitializedGlobals =
false;
1258 for (
size_t i = 0; i < n; i++) {
1259 static const uint64_t kMaxGlobalRedzone = 1 << 18;
1262 auto MD = GlobalsMD.get(G);
1270 Type *Ty = PtrTy->getElementType();
1271 uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
1272 uint64_t MinRZ = MinRedzoneSizeForGlobal();
1275 uint64_t
RZ = std::max(
1276 MinRZ,
std::min(kMaxGlobalRedzone, (SizeInBytes / MinRZ / 4) * MinRZ));
1277 uint64_t RightRedzoneSize =
RZ;
1279 if (SizeInBytes % MinRZ) RightRedzoneSize += MinRZ - (SizeInBytes % MinRZ);
1280 assert(((RightRedzoneSize + SizeInBytes) % MinRZ) == 0);
1294 "",
G, G->getThreadLocalMode());
1305 G->eraseFromParent();
1308 if (!MD.SourceLoc.empty()) {
1323 if (
ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals =
true;
1325 DEBUG(
dbgs() <<
"NEW GLOBAL: " << *NewGlobal <<
"\n");
1334 if (HasDynamicallyInitializedGlobals)
1335 createInitializerPoisonCalls(M, ModuleName);
1347 IRB_Dtor.CreateCall(AsanUnregisterGlobals,
1356 bool AddressSanitizerModule::runOnModule(
Module &M) {
1361 Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
1362 initializeCallbacks(M);
1364 bool Changed =
false;
1371 Changed |= InstrumentGlobals(IRB, M);
1377 void AddressSanitizer::initializeCallbacks(
Module &M) {
1381 for (
int Exp = 0; Exp < 2; Exp++) {
1382 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
1383 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
1384 const std::string ExpStr = Exp ?
"exp_" :
"";
1385 const std::string SuffixStr = CompileKernel ?
"N" :
"_n";
1386 const std::string EndingStr = CompileKernel ?
"_noabort" :
"";
1390 AsanErrorCallbackSized[AccessIsWrite][Exp] =
1393 IRB.
getVoidTy(), IntptrTy, IntptrTy, ExpType,
nullptr));
1394 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
1397 IRB.
getVoidTy(), IntptrTy, IntptrTy, ExpType,
nullptr));
1399 AccessSizeIndex++) {
1400 const std::string Suffix = TypeStr +
itostr(1 << AccessSizeIndex);
1401 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
1404 IRB.
getVoidTy(), IntptrTy, ExpType,
nullptr));
1405 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
1408 IRB.
getVoidTy(), IntptrTy, ExpType,
nullptr));
1413 const std::string MemIntrinCallbackPrefix =
1416 MemIntrinCallbackPrefix +
"memmove", IRB.
getInt8PtrTy(),
1419 MemIntrinCallbackPrefix +
"memcpy", IRB.
getInt8PtrTy(),
1422 MemIntrinCallbackPrefix +
"memset", IRB.
getInt8PtrTy(),
1439 bool AddressSanitizer::doInitialization(
Module &M) {
1449 if (!CompileKernel) {
1450 std::tie(AsanCtorFunction, AsanInitFunction) =
1456 Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
1460 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(
Function &F) {
1468 if (F.
getName().
find(
" load]") != std::string::npos) {
1476 bool AddressSanitizer::runOnFunction(
Function &F) {
1477 if (&F == AsanCtorFunction)
return false;
1479 DEBUG(
dbgs() <<
"ASAN instrumenting:\n" << F <<
"\n");
1482 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1485 maybeInsertAsanInitAtFunctionEntry(F);
1504 for (
auto &BB : F) {
1506 TempsToInstrument.
clear();
1507 int NumInsnsPerBB = 0;
1508 for (
auto &Inst : BB) {
1509 if (LooksLikeCodeInBug11395(&Inst))
return false;
1510 if (
Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
1513 if (!TempsToInstrument.
insert(Addr).second)
1518 PointerComparisonsOrSubtracts.
push_back(&Inst);
1520 }
else if (isa<MemIntrinsic>(Inst)) {
1523 if (isa<AllocaInst>(Inst)) NumAllocas++;
1527 TempsToInstrument.
clear();
1528 if (CS.doesNotReturn()) NoReturnCalls.
push_back(CS.getInstruction());
1543 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1544 const DataLayout &DL = F.getParent()->getDataLayout();
1549 int NumInstrumented = 0;
1550 for (
auto Inst : ToInstrument) {
1553 if (isInterestingMemoryAccess(Inst, &IsWrite, &TypeSize, &Alignment))
1554 instrumentMop(ObjSizeVis, Inst, UseCalls,
1555 F.getParent()->getDataLayout());
1557 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
1562 FunctionStackPoisoner FSP(F, *
this);
1563 bool ChangedStack = FSP.runOnFunction();
1567 for (
auto CI : NoReturnCalls) {
1572 for (
auto Inst : PointerComparisonsOrSubtracts) {
1573 instrumentPointerComparisonOrSubtraction(Inst);
1577 bool res = NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty();
1579 DEBUG(
dbgs() <<
"ASAN done instrumenting: " << res <<
" " << F <<
"\n");
1587 bool AddressSanitizer::LooksLikeCodeInBug11395(
Instruction *I) {
1588 if (LongSize != 32)
return false;
1596 void FunctionStackPoisoner::initializeCallbacks(
Module &M) {
1599 std::string Suffix =
itostr(i);
1602 IntptrTy,
nullptr));
1605 IRB.
getVoidTy(), IntptrTy, IntptrTy,
nullptr));
1609 IntptrTy, IntptrTy,
nullptr));
1612 IntptrTy, IntptrTy,
nullptr));
1615 AsanAllocasUnpoisonFunc =
1623 size_t n = ShadowBytes.
size();
1628 for (
size_t LargeStoreSizeInBytes = ASan.LongSize / 8;
1629 LargeStoreSizeInBytes != 0; LargeStoreSizeInBytes /= 2) {
1630 for (; i + LargeStoreSizeInBytes - 1 < n; i += LargeStoreSizeInBytes) {
1632 for (
size_t j = 0; j < LargeStoreSizeInBytes; j++) {
1633 if (F.getParent()->getDataLayout().isLittleEndian())
1634 Val |= (uint64_t)ShadowBytes[i + j] << (8 * j);
1636 Val = (Val << 8) | ShadowBytes[i + j];
1652 for (
int i = 0;; i++, MaxSize *= 2)
1653 if (LocalStackSize <= MaxSize)
return i;
1662 void FunctionStackPoisoner::SetShadowToStackAfterReturnInlined(
1664 assert(!(Size % 8));
1667 const uint64_t kAsanStackAfterReturnMagic64 = 0xf5f5f5f5f5f5f5f5ULL;
1669 for (
int i = 0; i < Size; i += 8) {
1680 Value *ValueIfFalse) {
1689 Value *FunctionStackPoisoner::createAllocaForLayout(
1698 nullptr,
"MyAlloca");
1707 void FunctionStackPoisoner::createDynamicAllocasInitStorage() {
1710 DynamicAllocaLayout = IRB.
CreateAlloca(IntptrTy,
nullptr);
1715 void FunctionStackPoisoner::poisonStack() {
1716 assert(AllocaVec.size() > 0 || DynamicAllocaVec.size() > 0);
1720 createDynamicAllocasInitStorage();
1721 for (
auto &AI : DynamicAllocaVec) handleDynamicAllocaCall(AI);
1723 unpoisonDynamicAllocas();
1726 if (AllocaVec.size() == 0)
return;
1728 int StackMallocIdx = -1;
1738 SVD.
reserve(AllocaVec.size());
1741 ASan.getAllocaSizeInBytes(AI),
1747 size_t MinHeaderSize = ASan.LongSize / 2;
1757 DoStackMalloc &= !HasNonEmptyInlineAsm;
1759 Value *StaticAlloca =
1760 DoDynamicAlloca ?
nullptr : createAllocaForLayout(IRB, L,
false);
1763 Value *LocalStackBase;
1765 if (DoStackMalloc) {
1770 Constant *OptionDetectUAR = F.getParent()->getOrInsertGlobal(
1772 Value *UARIsEnabled =
1778 IRBIf.SetCurrentDebugLocation(EntryDebugLocation);
1781 Value *FakeStackValue =
1782 IRBIf.CreateCall(AsanStackMallocFunc[StackMallocIdx],
1786 FakeStack = createPHI(IRB, UARIsEnabled, FakeStackValue, Term,
1789 Value *NoFakeStack =
1792 IRBIf.SetInsertPoint(Term);
1793 IRBIf.SetCurrentDebugLocation(EntryDebugLocation);
1794 Value *AllocaValue =
1795 DoDynamicAlloca ? createAllocaForLayout(IRBIf, L,
true) : StaticAlloca;
1798 LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack);
1804 DoDynamicAlloca ? createAllocaForLayout(IRB, L,
true) : StaticAlloca;
1808 bool HavePoisonedAllocas =
false;
1809 for (
const auto &APC : AllocaPoisonCallVec) {
1810 assert(APC.InsBefore);
1813 poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison);
1814 HavePoisonedAllocas |= APC.DoPoison;
1818 for (
const auto &Desc : SVD) {
1850 Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB);
1851 poisonRedZones(L.
ShadowBytes, IRB, ShadowBase,
true);
1854 for (
auto Ret : RetVec) {
1859 if (DoStackMalloc) {
1860 assert(StackMallocIdx >= 0);
1877 if (StackMallocIdx <= 4) {
1879 SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase,
1880 ClassSize >> Mapping.Scale);
1881 Value *SavedFlagPtrPtr = IRBPoison.CreateAdd(
1884 Value *SavedFlagPtr = IRBPoison.CreateLoad(
1885 IRBPoison.CreateIntToPtr(SavedFlagPtrPtr, IntptrPtrTy));
1886 IRBPoison.CreateStore(
1888 IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy()));
1891 IRBPoison.CreateCall(
1892 AsanStackFreeFunc[StackMallocIdx],
1897 poisonRedZones(L.
ShadowBytes, IRBElse, ShadowBase,
false);
1898 }
else if (HavePoisonedAllocas) {
1901 poisonAlloca(LocalStackBase, LocalStackSize, IRBRet,
false);
1903 poisonRedZones(L.
ShadowBytes, IRBRet, ShadowBase,
false);
1911 void FunctionStackPoisoner::poisonAlloca(
Value *V, uint64_t Size,
1917 DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc,
1918 {AddrArg, SizeArg});
1931 if (
AllocaInst *AI = dyn_cast<AllocaInst>(V))
1933 return ASan.isInterestingAlloca(*AI) ? AI :
nullptr;
1936 AllocaForValueMapTy::iterator I = AllocaForValue.find(V);
1937 if (I != AllocaForValue.end())
return I->second;
1940 AllocaForValue[V] =
nullptr;
1944 else if (
PHINode *PN = dyn_cast<PHINode>(V)) {
1945 for (
Value *IncValue : PN->incoming_values()) {
1947 if (IncValue == PN)
continue;
1948 AllocaInst *IncValueAI = findAllocaForValue(IncValue);
1950 if (IncValueAI ==
nullptr || (Res !=
nullptr && IncValueAI != Res))
1955 if (Res) AllocaForValue[V] = Res;
1959 void FunctionStackPoisoner::handleDynamicAllocaCall(
AllocaInst *AI) {
1973 const unsigned ElementSize =
2006 IRB.
CreateCall(AsanAllocaPoisonFunc, {NewAddress, OldSize});
2025 Value *Addr, uint64_t TypeSize)
const {
2027 if (!ObjSizeVis.
bothKnown(SizeOffset))
return false;
2028 uint64_t Size = SizeOffset.first.getZExtValue();
2029 int64_t Offset = SizeOffset.second.getSExtValue();
2034 return Offset >= 0 && Size >= uint64_t(Offset) &&
2035 Size - uint64_t(Offset) >= TypeSize / 8;
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
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...
ReturnInst - Return a value (possibly void), from a function.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
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
AllocaInst * CreateAlloca(Type *Ty, Value *ArraySize=nullptr, const Twine &Name="")
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
ReplaceInstWithInst - Replace the instruction specified by BI with the instruction specified by I...
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
getString - This method constructs a CDS and initializes it with a text string.
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))
LoadInst * CreateLoad(Value *Ptr, const char *Name)
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - 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...
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)
STATISTIC(NumFunctions,"Total number of functions")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
A Module instance is used to store all the information related to an LLVM module. ...
void setAlignment(unsigned Align)
Intrinsic::ID getIntrinsicID() const
getIntrinsicID - Return the intrinsic ID of this intrinsic.
AtomicCmpXchgInst - an instruction that atomically checks whether a specified value is in a memory lo...
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
getAnon - Return an anonymous struct that has the specified elements.
Available for inspection, not emission.
unsigned getNumOperands() const
Return number of MDNode operands.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
void appendToGlobalCtors(Module &M, Function *F, int Priority)
Append F to the list of global ctors of module M with the given Priority.
static const uintptr_t kCurrentStackFrameMagic
CallInst - This class represents a function call, abstracting a target machine's calling convention...
TerminatorInst * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr)
SplitBlockAndInsertIfThen - Split the containing block at the specified instruction - everything befo...
static PointerType * get(Type *ElementType, unsigned AddressSpace)
PointerType::get - This constructs a pointer to an object of the specified type in a numbered address...
static bool isInterestingPointerComparisonOrSubtraction(Instruction *I)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Like Internal, but omit from symbol table.
Externally visible function.
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))
const Function * getParent() const
Return the enclosing method, or null if none.
LoadInst - an instruction for reading from memory.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
AtomicRMWInst - an instruction that atomically reads a memory location, combines it with another valu...
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
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)
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.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
bool isOSWindows() const
Tests whether the OS is Windows.
static Constant * getNullValue(Type *Ty)
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
SmallVector< uint8_t, 64 > ShadowBytes
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
bool isArrayAllocation() const
isArrayAllocation - Return true if there is an allocation size parameter to the allocation instructio...
static const uint64_t kDefaultShadowScale
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static bool GlobalWasGeneratedByAsan(GlobalVariable *G)
bool isIdenticalTo(const Instruction *I) const
isIdenticalTo - Return true if the specified instruction is exactly identical to the current one...
DILocation * get() const
Get the underlying DILocation.
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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.
StructType - Class to represent struct types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const uint64_t kLinuxKasan_ShadowOffset64
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
A Use represents the edge between a Value definition and its users.
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug man inst"), cl::Hidden, cl::init(-1))
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
unsigned getNumArgOperands() const
getNumArgOperands - Return the number of call arguments.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
bool isSized(SmallPtrSetImpl< const Type * > *Visited=nullptr) const
isSized - Return true if it makes sense to take the size of this type.
static const char *const kAsanAllocasUnpoison
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static const char *const kAsanModuleCtorName
DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Type * getVoidTy()
Fetch the type representing void.
bool isOSLinux() const
Tests whether the OS is Linux.
static const char *const kAsanPoisonStackMemoryName
static const uint64_t kSmallX86_64ShadowOffset
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
static const char *const kSanCovGenPrefix
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
unsigned getAlignment() const
ArrayType - Class to represent array types.
static const int kMaxAsanStackMallocSizeClass
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
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
FunctionType::get - 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))
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
StoreInst - an instruction for storing to memory.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
static cl::opt< bool > ClUseAfterReturn("asan-use-after-return", cl::desc("Check return-after-free"), cl::Hidden, cl::init(true))
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))
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
SmallString< 64 > DescriptionString
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
iterator_range< op_iterator > operands()
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
PointerType - Class to represent pointers.
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 isiOS() const
Is this an iOS triple.
static const size_t kNumberOfAccessSizes
initializer< Ty > init(const Ty &Val)
static const char *const kAsanPtrCmp
static std::string ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
ParseSectionSpecifier - 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)
setDebugLoc - 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...
Value * CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name="")
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...
BranchInst - Conditional or Unconditional Branch instruction.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static const size_t kMinStackMallocSize
UnreachableInst - This function has undefined behavior.
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
This is an important base class in LLVM.
PointerType * getType() const
getType - Overload to return most specific pointer type
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...
static const uint64_t kMIPS32_ShadowOffset32
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
unsigned getAlignment() const
getAlignment - 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
getDebugLoc - 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)
This instruction compares its operands according to the predicate given to the constructor.
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.
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)
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
isPointerTy - True if this is an instance of PointerType.
static std::string itostr(int64_t X)
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="")
PointerType * getPointerTo(unsigned AddrSpace=0)
getPointerTo - Return a pointer to the current type.
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
void appendToGlobalDtors(Module &M, Function *F, int Priority)
Same as appendToGlobalCtors(), but for global dtors.
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
GetUnderlyingObject - This method strips off any GEP address adjustments and pointer casts from the s...
void initializeAddressSanitizerPass(PassRegistry &)
Triple - Helper class for working with autoconf configuration names.
static const char *const kAsanRegisterGlobalsName
const char * getSection() const
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
StringRef getString() const
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
const MDOperand & getOperand(unsigned I) const
MemIntrinsic - This is the common base class for memset/memcpy/memmove.
const BasicBlockListType & getBasicBlockList() const
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
This is the shared class of boolean and integer constants.
static const char *const kAsanStackMallocNameTemplate
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)
StructType::get - 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...
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
isStaticAlloca - Return true if this alloca is in the entry block of the function and is a constant s...
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
getMetadata - Get the metadata of given kind attached to this Instruction.
void setUnnamedAddr(bool Val)
INITIALIZE_PASS_BEGIN(AddressSanitizer,"asan","AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) INITIALIZE_PASS_END(AddressSanitizer
static const uint64_t kDefaultShadowOffset64
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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)
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 cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
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.
ConstantArray - Constant Array Declarations.
bool hasInitializer() const
Definitions have initializers, declarations don't.
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 replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, bool Deref)
Replaces llvm.dbg.declare instruction when an alloca is replaced with a new value.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="")
static cl::opt< bool > ClCheckLifetime("asan-check-lifetime", cl::desc("Use llvm.lifetime intrinsics to insert extra checks"), cl::Hidden, cl::init(false))
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isInlineAsm() const
isInlineAsm - Check if this call is an inline asm statement.
static cl::opt< bool > ClSkipPromotableAllocas("asan-skip-promotable-allocas", cl::desc("Do not instrument promotable allocas"), cl::Hidden, cl::init(true))
FunctionPass * createAddressSanitizerFunctionPass(bool CompileKernel=false)
PointerType * getType() const
Global values are always pointers.
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_"))
static const uint64_t kMIPS64_ShadowOffset64
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
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...
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 ...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
ArrayType::get - This static method is the primary way to construct an ArrayType. ...
std::pair< Function *, Function * > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
static cl::opt< bool > ClInstrumentAllocas("asan-instrument-allocas", cl::desc("instrument dynamic allocas"), cl::Hidden, cl::init(false))
Rename collisions when linking (static functions).
static const char *const kAsanOptionDetectUAR
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
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
EnvironmentType getEnvironment() const
getEnvironment - Get the parsed environment type of this triple.
static const char *const kAsanUnregisterGlobalsName
iterator_range< df_iterator< T > > depth_first(const T &G)
static const char *const kAsanUnpoisonGlobalsName
bool bothKnown(SizeOffsetType &SizeOffset)
void copyAttributesFrom(const GlobalValue *Src) override
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
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 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
getArraySize - Get the number of elements allocated.
static const Function * getParent(const Value *V)
static const char *const kAsanAllocaPoison
static const char *const kAsanHandleNoReturnName
iterator_range< global_iterator > globals()
C - The default llvm calling convention, compatible with C.
static const size_t kMaxStackMallocSize
StringRef - Represent a constant reference to a string, i.e.
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))
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
getAllocatedType - Return the type that is being allocated by the instruction.
const BasicBlock * getParent() const
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
void ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, size_t Granularity, size_t MinHeaderSize, ASanStackFrameLayout *Layout)
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))
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.
LLVMContext & getContext() const
Get the global data context.
AllocaInst - an instruction to allocate memory on the stack.
ModulePass * createAddressSanitizerModulePass(bool CompileKernel=false)
static const char *const kAsanReportErrorTemplate