#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
usingnamespacellvm;
#define DEBUG_TYPE …
const char SanCovTracePCIndirName[] = …;
const char SanCovTracePCName[] = …;
const char SanCovTraceCmp1[] = …;
const char SanCovTraceCmp2[] = …;
const char SanCovTraceCmp4[] = …;
const char SanCovTraceCmp8[] = …;
const char SanCovTraceConstCmp1[] = …;
const char SanCovTraceConstCmp2[] = …;
const char SanCovTraceConstCmp4[] = …;
const char SanCovTraceConstCmp8[] = …;
const char SanCovLoad1[] = …;
const char SanCovLoad2[] = …;
const char SanCovLoad4[] = …;
const char SanCovLoad8[] = …;
const char SanCovLoad16[] = …;
const char SanCovStore1[] = …;
const char SanCovStore2[] = …;
const char SanCovStore4[] = …;
const char SanCovStore8[] = …;
const char SanCovStore16[] = …;
const char SanCovTraceDiv4[] = …;
const char SanCovTraceDiv8[] = …;
const char SanCovTraceGep[] = …;
const char SanCovTraceSwitchName[] = …;
const char SanCovModuleCtorTracePcGuardName[] = …;
const char SanCovModuleCtor8bitCountersName[] = …;
const char SanCovModuleCtorBoolFlagName[] = …;
static const uint64_t SanCtorAndDtorPriority = …;
const char SanCovTracePCGuardName[] = …;
const char SanCovTracePCGuardInitName[] = …;
const char SanCov8bitCountersInitName[] = …;
const char SanCovBoolFlagInitName[] = …;
const char SanCovPCsInitName[] = …;
const char SanCovCFsInitName[] = …;
const char SanCovGuardsSectionName[] = …;
const char SanCovCountersSectionName[] = …;
const char SanCovBoolFlagSectionName[] = …;
const char SanCovPCsSectionName[] = …;
const char SanCovCFsSectionName[] = …;
const char SanCovLowestStackName[] = …;
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> ClTracePC("sanitizer-coverage-trace-pc",
cl::desc("Experimental pc tracing"), cl::Hidden);
static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
cl::desc("pc tracing with a guard"),
cl::Hidden);
static cl::opt<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
cl::desc("create a static PC table"),
cl::Hidden);
static cl::opt<bool>
ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters",
cl::desc("increments 8-bit counter for every edge"),
cl::Hidden);
static cl::opt<bool>
ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag",
cl::desc("sets a boolean flag for every edge"),
cl::Hidden);
static cl::opt<bool>
ClCMPTracing("sanitizer-coverage-trace-compares",
cl::desc("Tracing of CMP and similar instructions"),
cl::Hidden);
static cl::opt<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
cl::desc("Tracing of DIV instructions"),
cl::Hidden);
static cl::opt<bool> ClLoadTracing("sanitizer-coverage-trace-loads",
cl::desc("Tracing of load instructions"),
cl::Hidden);
static cl::opt<bool> ClStoreTracing("sanitizer-coverage-trace-stores",
cl::desc("Tracing of store instructions"),
cl::Hidden);
static cl::opt<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
cl::desc("Tracing of GEP instructions"),
cl::Hidden);
static cl::opt<bool>
ClPruneBlocks("sanitizer-coverage-prune-blocks",
cl::desc("Reduce the number of instrumented blocks"),
cl::Hidden, cl::init(true));
static cl::opt<bool> ClStackDepth("sanitizer-coverage-stack-depth",
cl::desc("max stack depth tracing"),
cl::Hidden);
static cl::opt<bool>
ClCollectCF("sanitizer-coverage-control-flow",
cl::desc("collect control flow for each function"), cl::Hidden);
namespace {
SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) { … }
SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) { … }
class ModuleSanitizerCoverage { … };
}
PreservedAnalyses SanitizerCoveragePass::run(Module &M,
ModuleAnalysisManager &MAM) { … }
std::pair<Value *, Value *>
ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
Type *Ty) { … }
Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
const char *Section) { … }
bool ModuleSanitizerCoverage::instrumentModule() { … }
static bool isFullDominator(const BasicBlock *BB, const DominatorTree &DT) { … }
static bool isFullPostDominator(const BasicBlock *BB,
const PostDominatorTree &PDT) { … }
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
const DominatorTree &DT,
const PostDominatorTree &PDT,
const SanitizerCoverageOptions &Options) { … }
static bool IsBackEdge(BasicBlock *From, BasicBlock *To,
const DominatorTree &DT) { … }
static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree &DT,
const SanitizerCoverageOptions &Options) { … }
void ModuleSanitizerCoverage::instrumentFunction(Function &F) { … }
GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
size_t NumElements, Function &F, Type *Ty, const char *Section) { … }
GlobalVariable *
ModuleSanitizerCoverage::CreatePCArray(Function &F,
ArrayRef<BasicBlock *> AllBlocks) { … }
void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
Function &F, ArrayRef<BasicBlock *> AllBlocks) { … }
bool ModuleSanitizerCoverage::InjectCoverage(Function &F,
ArrayRef<BasicBlock *> AllBlocks,
bool IsLeafFunc) { … }
void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
Function &F, ArrayRef<Instruction *> IndirCalls) { … }
void ModuleSanitizerCoverage::InjectTraceForSwitch(
Function &, ArrayRef<Instruction *> SwitchTraceTargets) { … }
void ModuleSanitizerCoverage::InjectTraceForDiv(
Function &, ArrayRef<BinaryOperator *> DivTraceTargets) { … }
void ModuleSanitizerCoverage::InjectTraceForGep(
Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) { … }
void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
Function &, ArrayRef<LoadInst *> Loads, ArrayRef<StoreInst *> Stores) { … }
void ModuleSanitizerCoverage::InjectTraceForCmp(
Function &, ArrayRef<Instruction *> CmpTraceTargets) { … }
void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
size_t Idx,
bool IsLeafFunc) { … }
std::string
ModuleSanitizerCoverage::getSectionName(const std::string &Section) const { … }
std::string
ModuleSanitizerCoverage::getSectionStart(const std::string &Section) const { … }
std::string
ModuleSanitizerCoverage::getSectionEnd(const std::string &Section) const { … }
void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) { … }