42#define DEBUG_TYPE "sancov"
69 "sancov.module_ctor_trace_pc_guard";
71 "sancov.module_ctor_8bit_counters";
93 "sanitizer-coverage-level",
94 cl::desc(
"Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
95 "3: all blocks and critical edges"),
102 cl::desc(
"pc tracing with a guard"),
112 cl::desc(
"create a static PC table"),
117 cl::desc(
"increments 8-bit counter for every edge"),
122 cl::desc(
"sets a boolean flag for every edge"),
127 cl::desc(
"Tracing of CMP and similar instructions"),
131 cl::desc(
"Tracing of DIV instructions"),
135 cl::desc(
"Tracing of load instructions"),
139 cl::desc(
"Tracing of store instructions"),
143 cl::desc(
"Tracing of GEP instructions"),
148 cl::desc(
"Reduce the number of instrumented blocks"),
152 cl::desc(
"max stack depth tracing"),
160 "sanitizer-coverage-gated-trace-callbacks",
161 cl::desc(
"Gate the invocation of the tracing callbacks on a global variable"
162 ". Currently only supported for trace-pc-guard and trace-cmp."),
169 switch (LegacyCoverageLevel) {
216class ModuleSanitizerCoverage {
219 using PostDomTreeCallback =
222 ModuleSanitizerCoverage(
Module &M, DomTreeCallback DTCallback,
223 PostDomTreeCallback PDTCallback,
227 :
M(
M), DTCallback(DTCallback), PDTCallback(PDTCallback),
228 Options(Options), Allowlist(Allowlist), Blocklist(Blocklist) {}
230 bool instrumentModule();
233 void createFunctionControlFlow(
Function &
F);
235 void InjectCoverageForIndirectCalls(
Function &
F,
238 Value *&FunctionGateCmp);
247 Value *&FunctionGateCmp);
249 Value *&FunctionGateCmp,
bool IsLeafFunc);
250 GlobalVariable *CreateFunctionLocalArrayInSection(
size_t NumElements,
252 const char *Section);
259 Value *&FunctionGateCmp,
bool IsLeafFunc);
260 Function *CreateInitCallsForSections(
Module &M,
const char *CtorName,
261 const char *InitFunctionName,
Type *Ty,
262 const char *Section);
263 std::pair<Value *, Value *> CreateSecStartEnd(
Module &M,
const char *Section,
267 std::string getSectionStart(
const std::string &Section)
const;
268 std::string getSectionEnd(
const std::string &Section)
const;
271 DomTreeCallback DTCallback;
272 PostDomTreeCallback PDTCallback;
276 std::array<FunctionCallee, 4> SanCovTraceCmpFunction;
277 std::array<FunctionCallee, 4> SanCovTraceConstCmpFunction;
278 std::array<FunctionCallee, 5> SanCovLoadFunction;
279 std::array<FunctionCallee, 5> SanCovStoreFunction;
280 std::array<FunctionCallee, 2> SanCovTraceDivFunction;
285 Type *PtrTy, *IntptrTy, *Int64Ty, *Int32Ty, *Int16Ty, *Int8Ty, *Int1Ty;
287 std::string CurModuleUniqueId;
316 ModuleSanitizerCoverage ModuleSancov(M, DTCallback, PDTCallback,
317 OverrideFromCL(Options), Allowlist.get(),
319 if (!ModuleSancov.instrumentModule())
330std::pair<Value *, Value *>
331ModuleSanitizerCoverage::CreateSecStartEnd(
Module &M,
const char *Section,
342 getSectionStart(Section));
346 getSectionEnd(Section));
349 if (!TargetTriple.isOSBinFormatCOFF())
350 return std::make_pair(SecStart, SecEnd);
355 IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy,
sizeof(
uint64_t)));
356 return std::make_pair(
GEP, SecEnd);
359Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
360 Module &M,
const char *CtorName,
const char *InitFunctionName,
Type *Ty,
361 const char *Section) {
362 auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
363 auto SecStart = SecStartEnd.first;
364 auto SecEnd = SecStartEnd.second;
367 M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
370 if (TargetTriple.supportsCOMDAT()) {
372 CtorFunc->
setComdat(
M.getOrInsertComdat(CtorName));
378 if (TargetTriple.isOSBinFormatCOFF()) {
390bool ModuleSanitizerCoverage::instrumentModule() {
394 !Allowlist->inSection(
"coverage",
"src",
M.getSourceFileName()))
397 Blocklist->inSection(
"coverage",
"src",
M.getSourceFileName()))
399 C = &(
M.getContext());
400 DL = &
M.getDataLayout();
403 TargetTriple =
Triple(
M.getTargetTriple());
404 FunctionGuardArray =
nullptr;
405 Function8bitCounterArray =
nullptr;
406 FunctionBoolArray =
nullptr;
407 FunctionPCsArray =
nullptr;
408 FunctionCFsArray =
nullptr;
413 Int64Ty = IRB.getInt64Ty();
414 Int32Ty = IRB.getInt32Ty();
415 Int16Ty = IRB.getInt16Ty();
416 Int8Ty = IRB.getInt8Ty();
417 Int1Ty = IRB.getInt1Ty();
424 SanCovTraceCmpZeroExtAL =
426 SanCovTraceCmpZeroExtAL =
429 SanCovTraceCmpFunction[0] =
431 IRB.getInt8Ty(), IRB.getInt8Ty());
432 SanCovTraceCmpFunction[1] =
434 IRB.getInt16Ty(), IRB.getInt16Ty());
435 SanCovTraceCmpFunction[2] =
437 IRB.getInt32Ty(), IRB.getInt32Ty());
438 SanCovTraceCmpFunction[3] =
441 SanCovTraceConstCmpFunction[0] =
M.getOrInsertFunction(
443 SanCovTraceConstCmpFunction[1] =
M.getOrInsertFunction(
445 SanCovTraceConstCmpFunction[2] =
M.getOrInsertFunction(
447 SanCovTraceConstCmpFunction[3] =
451 SanCovLoadFunction[0] =
M.getOrInsertFunction(
SanCovLoad1, VoidTy, PtrTy);
452 SanCovLoadFunction[1] =
454 SanCovLoadFunction[2] =
456 SanCovLoadFunction[3] =
458 SanCovLoadFunction[4] =
461 SanCovStoreFunction[0] =
463 SanCovStoreFunction[1] =
465 SanCovStoreFunction[2] =
467 SanCovStoreFunction[3] =
469 SanCovStoreFunction[4] =
474 AL =
AL.addParamAttribute(*
C, 0, Attribute::ZExt);
475 SanCovTraceDivFunction[0] =
478 SanCovTraceDivFunction[1] =
480 SanCovTraceGepFunction =
482 SanCovTraceSwitchFunction =
485 Constant *SanCovLowestStackConstant =
487 SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
488 if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
490 "' should not be declared by the user");
493 SanCovLowestStack->setThreadLocalMode(
495 if (
Options.StackDepth && !SanCovLowestStack->isDeclaration())
501 "' is only supported with trace-pc-guard or trace-cmp");
505 SanCovCallbackGate = cast<GlobalVariable>(
507 SanCovCallbackGate->setSection(
520 instrumentFunction(
F);
524 if (FunctionGuardArray)
528 if (Function8bitCounterArray)
532 if (FunctionBoolArray) {
542 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
545 if (Ctor &&
Options.CollectControlFlow) {
550 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
596 if (
Options.NoPrune || &
F.getEntryBlock() == BB)
600 &
F.getEntryBlock() != BB)
631 if (CMP->hasOneUse())
632 if (
auto BR = dyn_cast<BranchInst>(CMP->user_back()))
639void ModuleSanitizerCoverage::instrumentFunction(
Function &
F) {
642 if (
F.getName().contains(
".module_ctor"))
644 if (
F.getName().starts_with(
"__sanitizer_"))
651 if (
F.getName() ==
"__local_stdio_printf_options" ||
652 F.getName() ==
"__local_stdio_scanf_options")
654 if (isa<UnreachableInst>(
F.getEntryBlock().getTerminator()))
659 if (
F.hasPersonalityFn() &&
662 if (Allowlist && !Allowlist->inSection(
"coverage",
"fun",
F.getName()))
664 if (Blocklist && Blocklist->inSection(
"coverage",
"fun",
F.getName()))
667 if (
F.hasFnAttribute(Attribute::Naked))
669 if (
F.hasFnAttribute(Attribute::NoSanitizeCoverage))
671 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
688 bool IsLeafFunc =
true;
693 for (
auto &Inst : BB) {
695 CallBase *CB = dyn_cast<CallBase>(&Inst);
700 if (
ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst))
703 if (isa<SwitchInst>(&Inst))
708 if (BO->getOpcode() == Instruction::SDiv ||
709 BO->getOpcode() == Instruction::UDiv)
715 if (
LoadInst *LI = dyn_cast<LoadInst>(&Inst))
718 if (
StoreInst *SI = dyn_cast<StoreInst>(&Inst))
721 if (isa<InvokeInst>(Inst) ||
722 (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst)))
727 if (
Options.CollectControlFlow)
728 createFunctionControlFlow(
F);
730 Value *FunctionGateCmp =
nullptr;
731 InjectCoverage(
F, BlocksToInstrument, FunctionGateCmp, IsLeafFunc);
732 InjectCoverageForIndirectCalls(
F, IndirCalls);
733 InjectTraceForCmp(
F, CmpTraceTargets, FunctionGateCmp);
734 InjectTraceForSwitch(
F, SwitchTraceTargets, FunctionGateCmp);
735 InjectTraceForDiv(
F, DivTraceTargets);
736 InjectTraceForGep(
F, GepTraceTargets);
737 InjectTraceForLoadsAndStores(
F, Loads, Stores);
740GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
741 size_t NumElements,
Function &
F,
Type *Ty,
const char *Section) {
747 if (TargetTriple.supportsCOMDAT() &&
748 (TargetTriple.isOSBinFormatELF() || !
F.isInterposable()))
752 Array->setAlignment(
Align(
DL->getTypeStoreSize(Ty).getFixedValue()));
763 if (
Array->hasComdat())
764 GlobalsToAppendToCompilerUsed.push_back(Array);
766 GlobalsToAppendToUsed.push_back(Array);
772ModuleSanitizerCoverage::CreatePCArray(
Function &
F,
774 size_t N = AllBlocks.
size();
777 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
778 for (
size_t i = 0; i <
N; i++) {
779 if (&
F.getEntryBlock() == AllBlocks[i]) {
782 ConstantInt::get(IntptrTy, 1), PtrTy));
789 auto *PCArray = CreateFunctionLocalArrayInSection(
N * 2,
F, PtrTy,
791 PCArray->setInitializer(
793 PCArray->setConstant(
true);
798void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
801 FunctionGuardArray = CreateFunctionLocalArrayInSection(
804 if (
Options.Inline8bitCounters)
805 Function8bitCounterArray = CreateFunctionLocalArrayInSection(
808 FunctionBoolArray = CreateFunctionLocalArrayInSection(
812 FunctionPCsArray = CreatePCArray(
F, AllBlocks);
815Value *ModuleSanitizerCoverage::CreateFunctionLocalGateCmp(
IRBuilder<> &IRB) {
817 Load->setNoSanitizeMetadata();
819 Cmp->setName(
"sancov gate cmp");
824 Value *&FunctionGateCmp,
826 if (!FunctionGateCmp) {
832 FunctionGateCmp = CreateFunctionLocalGateCmp(EntryIRB);
841bool ModuleSanitizerCoverage::InjectCoverage(
Function &
F,
843 Value *&FunctionGateCmp,
845 if (AllBlocks.
empty())
return false;
846 CreateFunctionLocalArrays(
F, AllBlocks);
847 for (
size_t i = 0,
N = AllBlocks.
size(); i <
N; i++)
848 InjectCoverageAtBlock(
F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
859void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
861 if (IndirCalls.
empty())
865 for (
auto *
I : IndirCalls) {
869 if (isa<InlineAsm>(Callee))
879void ModuleSanitizerCoverage::InjectTraceForSwitch(
881 Value *&FunctionGateCmp) {
882 for (
auto *
I : SwitchTraceTargets) {
887 if (
Cond->getType()->getScalarSizeInBits() >
888 Int64Ty->getScalarSizeInBits())
890 Initializers.
push_back(ConstantInt::get(Int64Ty,
SI->getNumCases()));
892 ConstantInt::get(Int64Ty,
Cond->getType()->getScalarSizeInBits()));
893 if (
Cond->getType()->getScalarSizeInBits() <
894 Int64Ty->getScalarSizeInBits())
896 for (
auto It :
SI->cases()) {
898 if (
C->getType()->getScalarSizeInBits() < 64)
899 C = ConstantInt::get(
C->getContext(),
C->getValue().zext(64));
904 return cast<ConstantInt>(
A)->getLimitedValue() <
905 cast<ConstantInt>(
B)->getLimitedValue();
911 "__sancov_gen_cov_switch_values");
913 auto GateBranch = CreateGateBranch(
F, FunctionGateCmp,
I);
915 GateIRB.CreateCall(SanCovTraceSwitchFunction, {
Cond, GV});
923void ModuleSanitizerCoverage::InjectTraceForDiv(
925 for (
auto *BO : DivTraceTargets) {
927 Value *A1 = BO->getOperand(1);
928 if (isa<ConstantInt>(A1))
continue;
932 int CallbackIdx =
TypeSize == 32 ? 0 :
934 if (CallbackIdx < 0)
continue;
936 IRB.
CreateCall(SanCovTraceDivFunction[CallbackIdx],
941void ModuleSanitizerCoverage::InjectTraceForGep(
943 for (
auto *
GEP : GepTraceTargets) {
946 if (!isa<ConstantInt>(
Idx) &&
Idx->getType()->isIntegerTy())
952void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
954 auto CallbackIdx = [&](
Type *ElementTy) ->
int {
963 for (
auto *LI : Loads) {
965 auto Ptr = LI->getPointerOperand();
966 int Idx = CallbackIdx(LI->getType());
971 for (
auto *SI : Stores) {
973 auto Ptr =
SI->getPointerOperand();
974 int Idx = CallbackIdx(
SI->getValueOperand()->getType());
981void ModuleSanitizerCoverage::InjectTraceForCmp(
983 Value *&FunctionGateCmp) {
984 for (
auto *
I : CmpTraceTargets) {
985 if (
ICmpInst *ICMP = dyn_cast<ICmpInst>(
I)) {
992 int CallbackIdx =
TypeSize == 8 ? 0 :
996 if (CallbackIdx < 0)
continue;
998 auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
999 bool FirstIsConst = isa<ConstantInt>(A0);
1000 bool SecondIsConst = isa<ConstantInt>(A1);
1002 if (FirstIsConst && SecondIsConst)
continue;
1004 if (FirstIsConst || SecondIsConst) {
1005 CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
1012 auto GateBranch = CreateGateBranch(
F, FunctionGateCmp,
I);
1014 GateIRB.CreateCall(CallbackFunc, {GateIRB.CreateIntCast(A0, Ty,
true),
1015 GateIRB.CreateIntCast(A1, Ty,
true)});
1026 Value *&FunctionGateCmp,
1029 bool IsEntryBB = &BB == &
F.getEntryBlock();
1032 if (
auto SP =
F.getSubprogram())
1033 EntryLoc =
DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
1049 FunctionGuardArray->getValueType(), FunctionGuardArray, 0,
Idx);
1052 auto GateBranch = CreateGateBranch(
F, FunctionGateCmp,
I);
1054 GateIRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
1059 if (
Options.Inline8bitCounters) {
1061 Function8bitCounterArray->getValueType(), Function8bitCounterArray,
1062 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1064 auto Inc = IRB.
CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
1066 Load->setNoSanitizeMetadata();
1067 Store->setNoSanitizeMetadata();
1071 FunctionBoolArray->getValueType(), FunctionBoolArray,
1072 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1079 Load->setNoSanitizeMetadata();
1080 Store->setNoSanitizeMetadata();
1082 if (
Options.StackDepth && IsEntryBB && !IsLeafFunc) {
1086 Intrinsic::frameaddress,
1087 IRB.
getPtrTy(
M->getDataLayout().getAllocaAddrSpace()),
1088 {Constant::getNullValue(Int32Ty)});
1090 auto LowestStack = IRB.
CreateLoad(IntptrTy, SanCovLowestStack);
1091 auto IsStackLower = IRB.
CreateICmpULT(FrameAddrInt, LowestStack);
1093 IsStackLower, &*IP,
false,
1096 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
1097 LowestStack->setNoSanitizeMetadata();
1098 Store->setNoSanitizeMetadata();
1103ModuleSanitizerCoverage::getSectionName(
const std::string &Section)
const {
1104 if (TargetTriple.isOSBinFormatCOFF()) {
1113 if (TargetTriple.isOSBinFormatMachO())
1119ModuleSanitizerCoverage::getSectionStart(
const std::string &Section)
const {
1120 if (TargetTriple.isOSBinFormatMachO())
1121 return "\1section$start$__DATA$__" +
Section;
1122 return "__start___" +
Section;
1126ModuleSanitizerCoverage::getSectionEnd(
const std::string &Section)
const {
1127 if (TargetTriple.isOSBinFormatMachO())
1128 return "\1section$end$__DATA$__" +
Section;
1132void ModuleSanitizerCoverage::createFunctionControlFlow(
Function &
F) {
1134 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
1136 for (
auto &BB :
F) {
1138 if (&BB == &
F.getEntryBlock())
1145 assert(SuccBB != &
F.getEntryBlock());
1152 for (
auto &Inst : BB) {
1153 if (
CallBase *CB = dyn_cast<CallBase>(&Inst)) {
1157 ConstantInt::get(IntptrTy, -1), PtrTy));
1160 if (CalledF && !CalledF->isIntrinsic())
1170 FunctionCFsArray = CreateFunctionLocalArrayInSection(
1172 FunctionCFsArray->setInitializer(
1174 FunctionCFsArray->setConstant(
true);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
static cl::opt< bool > SplitAllCriticalEdges("phi-elim-split-all-critical-edges", cl::init(false), cl::Hidden, cl::desc("Split all critical edges during " "PHI elimination"))
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > ClLoadTracing("sanitizer-coverage-trace-loads", cl::desc("Tracing of load instructions"), cl::Hidden)
const char SanCovCFsSectionName[]
static bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree &PDT)
static cl::opt< int > ClCoverageLevel("sanitizer-coverage-level", cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, " "3: all blocks and critical edges"), cl::Hidden)
static cl::opt< bool > ClStackDepth("sanitizer-coverage-stack-depth", cl::desc("max stack depth tracing"), cl::Hidden)
static cl::opt< bool > ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag", cl::desc("sets a boolean flag for every edge"), cl::Hidden)
const char SanCovTraceConstCmp4[]
const char SanCovBoolFlagSectionName[]
const char SanCov8bitCountersInitName[]
const char SanCovTraceSwitchName[]
const char SanCovTraceCmp1[]
const char SanCovModuleCtorTracePcGuardName[]
const char SanCovCountersSectionName[]
static cl::opt< bool > ClCreatePCTable("sanitizer-coverage-pc-table", cl::desc("create a static PC table"), cl::Hidden)
const char SanCovPCsInitName[]
const char SanCovTracePCGuardName[]
const char SanCovModuleCtor8bitCountersName[]
const char SanCovTracePCGuardInitName[]
static cl::opt< bool > ClCollectCF("sanitizer-coverage-control-flow", cl::desc("collect control flow for each function"), cl::Hidden)
const char SanCovTraceDiv4[]
static const uint64_t SanCtorAndDtorPriority
const char SanCovBoolFlagInitName[]
static cl::opt< bool > ClGatedCallbacks("sanitizer-coverage-gated-trace-callbacks", cl::desc("Gate the invocation of the tracing callbacks on a global variable" ". Currently only supported for trace-pc-guard and trace-cmp."), cl::Hidden, cl::init(false))
const char SanCovTraceGep[]
const char SanCovLoad16[]
const char SanCovTraceConstCmp8[]
const char SanCovGuardsSectionName[]
const char SanCovStore1[]
const char SanCovTraceConstCmp2[]
const char SanCovTraceConstCmp1[]
static bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree &DT)
static cl::opt< bool > ClStoreTracing("sanitizer-coverage-trace-stores", cl::desc("Tracing of store instructions"), cl::Hidden)
const char SanCovCallbackGateName[]
static cl::opt< bool > ClTracePCGuard("sanitizer-coverage-trace-pc-guard", cl::desc("pc tracing with a guard"), cl::Hidden)
const char SanCovTraceDiv8[]
static cl::opt< bool > ClGEPTracing("sanitizer-coverage-trace-geps", cl::desc("Tracing of GEP instructions"), cl::Hidden)
const char SanCovCFsInitName[]
static cl::opt< bool > ClTracePC("sanitizer-coverage-trace-pc", cl::desc("Experimental pc tracing"), cl::Hidden)
const char SanCovStore2[]
static cl::opt< bool > ClPruneBlocks("sanitizer-coverage-prune-blocks", cl::desc("Reduce the number of instrumented blocks"), cl::Hidden, cl::init(true))
const char SanCovPCsSectionName[]
static bool isFullDominator(const BasicBlock *BB, const DominatorTree &DT)
static cl::opt< bool > ClCMPTracing("sanitizer-coverage-trace-compares", cl::desc("Tracing of CMP and similar instructions"), cl::Hidden)
const char SanCovTraceCmp8[]
const char SanCovCallbackGateSectionName[]
const char SanCovStore16[]
static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree &DT, const SanitizerCoverageOptions &Options)
static cl::opt< bool > ClDIVTracing("sanitizer-coverage-trace-divs", cl::desc("Tracing of DIV instructions"), cl::Hidden)
static cl::opt< bool > ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters", cl::desc("increments 8-bit counter for every edge"), cl::Hidden)
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, const DominatorTree &DT, const PostDominatorTree &PDT, const SanitizerCoverageOptions &Options)
const char SanCovModuleCtorBoolFlagName[]
const char SanCovTraceCmp2[]
const char SanCovStore8[]
const char SanCovTracePCName[]
const char SanCovStore4[]
const char SanCovTraceCmp4[]
const char SanCovLowestStackName[]
const char SanCovTracePCIndirName[]
This file defines the SmallVector class.
Defines the virtual file system interface vfs::FileSystem.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const
Add an argument attribute to the list.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction * getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic,...
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isIndirectCall() const
Return true if the callsite is an indirect call.
Value * getCalledOperand() const
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
const BasicBlock & getEntryBlock() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
void setComdat(Comdat *C)
void setLinkage(LinkageTypes LT)
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
LLVMContext & getContext() const
Value * CreateConstInBoundsGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void abandon()
Mark an analysis as abandoned.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This is a utility class used to parse user-provided text files with "special case lists" for code san...
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static Type * getVoidTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
An efficient, type-erasing, non-owning reference to a callable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool succ_empty(const Instruction *I)
auto successors(const MachineBasicBlock *BB)
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
void sort(IteratorTy Start, IteratorTy End)
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Comdat * getOrCreateFunctionComdat(Function &F, Triple &T)
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
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.
auto predecessors(const MachineBasicBlock *BB)
bool pred_empty(const BasicBlock *BB)
BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB, BasicBlock::iterator IP)
Instrumentation passes often insert conditional checks into entry blocks.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Option class for critical edge splitting.
enum llvm::SanitizerCoverageOptions::Type CoverageType