|
|
@ -52,49 +52,39 @@ using namespace llvm;
|
|
|
|
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "sancov"
|
|
|
|
#define DEBUG_TYPE "sancov"
|
|
|
|
|
|
|
|
|
|
|
|
static const char *const SanCovTracePCIndirName =
|
|
|
|
const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
|
|
|
|
"__sanitizer_cov_trace_pc_indir";
|
|
|
|
const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
|
|
|
|
static const char *const SanCovTracePCName = "__sanitizer_cov_trace_pc";
|
|
|
|
const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
|
|
|
|
static const char *const SanCovTraceCmp1 = "__sanitizer_cov_trace_cmp1";
|
|
|
|
const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
|
|
|
|
static const char *const SanCovTraceCmp2 = "__sanitizer_cov_trace_cmp2";
|
|
|
|
const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4";
|
|
|
|
static const char *const SanCovTraceCmp4 = "__sanitizer_cov_trace_cmp4";
|
|
|
|
const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8";
|
|
|
|
static const char *const SanCovTraceCmp8 = "__sanitizer_cov_trace_cmp8";
|
|
|
|
const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
|
|
|
|
static const char *const SanCovTraceConstCmp1 =
|
|
|
|
const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
|
|
|
|
"__sanitizer_cov_trace_const_cmp1";
|
|
|
|
const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
|
|
|
|
static const char *const SanCovTraceConstCmp2 =
|
|
|
|
const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
|
|
|
|
"__sanitizer_cov_trace_const_cmp2";
|
|
|
|
const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4";
|
|
|
|
static const char *const SanCovTraceConstCmp4 =
|
|
|
|
const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8";
|
|
|
|
"__sanitizer_cov_trace_const_cmp4";
|
|
|
|
const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep";
|
|
|
|
static const char *const SanCovTraceConstCmp8 =
|
|
|
|
const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
|
|
|
|
"__sanitizer_cov_trace_const_cmp8";
|
|
|
|
const char SanCovModuleCtorTracePcGuardName[] =
|
|
|
|
static const char *const SanCovTraceDiv4 = "__sanitizer_cov_trace_div4";
|
|
|
|
|
|
|
|
static const char *const SanCovTraceDiv8 = "__sanitizer_cov_trace_div8";
|
|
|
|
|
|
|
|
static const char *const SanCovTraceGep = "__sanitizer_cov_trace_gep";
|
|
|
|
|
|
|
|
static const char *const SanCovTraceSwitchName = "__sanitizer_cov_trace_switch";
|
|
|
|
|
|
|
|
static const char *const SanCovModuleCtorTracePcGuardName =
|
|
|
|
|
|
|
|
"sancov.module_ctor_trace_pc_guard";
|
|
|
|
"sancov.module_ctor_trace_pc_guard";
|
|
|
|
static const char *const SanCovModuleCtor8bitCountersName =
|
|
|
|
const char SanCovModuleCtor8bitCountersName[] =
|
|
|
|
"sancov.module_ctor_8bit_counters";
|
|
|
|
"sancov.module_ctor_8bit_counters";
|
|
|
|
static const char *const SanCovModuleCtorBoolFlagName =
|
|
|
|
const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag";
|
|
|
|
"sancov.module_ctor_bool_flag";
|
|
|
|
|
|
|
|
static const uint64_t SanCtorAndDtorPriority = 2;
|
|
|
|
static const uint64_t SanCtorAndDtorPriority = 2;
|
|
|
|
|
|
|
|
|
|
|
|
static const char *const SanCovTracePCGuardName =
|
|
|
|
const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
|
|
|
|
"__sanitizer_cov_trace_pc_guard";
|
|
|
|
const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
|
|
|
|
static const char *const SanCovTracePCGuardInitName =
|
|
|
|
const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
|
|
|
|
"__sanitizer_cov_trace_pc_guard_init";
|
|
|
|
const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
|
|
|
|
static const char *const SanCov8bitCountersInitName =
|
|
|
|
const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
|
|
|
|
"__sanitizer_cov_8bit_counters_init";
|
|
|
|
|
|
|
|
static const char *const SanCovBoolFlagInitName =
|
|
|
|
|
|
|
|
"__sanitizer_cov_bool_flag_init";
|
|
|
|
|
|
|
|
static const char *const SanCovPCsInitName = "__sanitizer_cov_pcs_init";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const char *const SanCovGuardsSectionName = "sancov_guards";
|
|
|
|
const char SanCovGuardsSectionName[] = "sancov_guards";
|
|
|
|
static const char *const SanCovCountersSectionName = "sancov_cntrs";
|
|
|
|
const char SanCovCountersSectionName[] = "sancov_cntrs";
|
|
|
|
static const char *const SanCovBoolFlagSectionName = "sancov_bools";
|
|
|
|
const char SanCovBoolFlagSectionName[] = "sancov_bools";
|
|
|
|
static const char *const SanCovPCsSectionName = "sancov_pcs";
|
|
|
|
const char SanCovPCsSectionName[] = "sancov_pcs";
|
|
|
|
|
|
|
|
|
|
|
|
static const char *const SanCovLowestStackName = "__sancov_lowest_stack";
|
|
|
|
const char SanCovLowestStackName[] = "__sancov_lowest_stack";
|
|
|
|
|
|
|
|
|
|
|
|
static char *skip_nozero;
|
|
|
|
static char *skip_nozero;
|
|
|
|
|
|
|
|
|
|
|
@ -320,12 +310,12 @@ std::pair<Value *, Value *> ModuleSanitizerCoverage::CreateSecStartEnd(
|
|
|
|
Module &M, const char *Section, Type *Ty) {
|
|
|
|
Module &M, const char *Section, Type *Ty) {
|
|
|
|
|
|
|
|
|
|
|
|
GlobalVariable *SecStart = new GlobalVariable(
|
|
|
|
GlobalVariable *SecStart = new GlobalVariable(
|
|
|
|
M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage,
|
|
|
|
M, Ty->getPointerElementType(), false,
|
|
|
|
nullptr, getSectionStart(Section));
|
|
|
|
GlobalVariable::ExternalWeakLinkage, nullptr, getSectionStart(Section));
|
|
|
|
SecStart->setVisibility(GlobalValue::HiddenVisibility);
|
|
|
|
SecStart->setVisibility(GlobalValue::HiddenVisibility);
|
|
|
|
GlobalVariable *SecEnd = new GlobalVariable(
|
|
|
|
GlobalVariable *SecEnd = new GlobalVariable(
|
|
|
|
M, Ty->getPointerElementType(), false, GlobalVariable::ExternalLinkage,
|
|
|
|
M, Ty->getPointerElementType(), false,
|
|
|
|
nullptr, getSectionEnd(Section));
|
|
|
|
GlobalVariable::ExternalWeakLinkage, nullptr, getSectionEnd(Section));
|
|
|
|
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
|
|
|
|
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
|
|
|
|
IRBuilder<> IRB(M.getContext());
|
|
|
|
IRBuilder<> IRB(M.getContext());
|
|
|
|
if (!TargetTriple.isOSBinFormatCOFF())
|
|
|
|
if (!TargetTriple.isOSBinFormatCOFF())
|
|
|
@ -573,7 +563,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// True if block has successors and it dominates all of them.
|
|
|
|
// True if block has successors and it dominates all of them.
|
|
|
|
static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
|
|
|
|
bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
|
|
|
|
|
|
|
|
|
|
|
|
if (succ_begin(BB) == succ_end(BB)) return false;
|
|
|
|
if (succ_begin(BB) == succ_end(BB)) return false;
|
|
|
|
|
|
|
|
|
|
|
@ -588,8 +578,7 @@ static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// True if block has predecessors and it postdominates all of them.
|
|
|
|
// True if block has predecessors and it postdominates all of them.
|
|
|
|
static bool isFullPostDominator(const BasicBlock * BB,
|
|
|
|
bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT) {
|
|
|
|
const PostDominatorTree *PDT) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pred_begin(BB) == pred_end(BB)) return false;
|
|
|
|
if (pred_begin(BB) == pred_end(BB)) return false;
|
|
|
|
|
|
|
|
|
|
|
@ -603,7 +592,7 @@ static bool isFullPostDominator(const BasicBlock * BB,
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
|
|
|
|
bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
|
|
|
|
const DominatorTree * DT,
|
|
|
|
const DominatorTree * DT,
|
|
|
|
const PostDominatorTree * PDT,
|
|
|
|
const PostDominatorTree * PDT,
|
|
|
|
const SanitizerCoverageOptions &Options) {
|
|
|
|
const SanitizerCoverageOptions &Options) {
|
|
|
@ -636,8 +625,7 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
|
|
|
|
// A twist here is that we treat From->To as a backedge if
|
|
|
|
// A twist here is that we treat From->To as a backedge if
|
|
|
|
// * To dominates From or
|
|
|
|
// * To dominates From or
|
|
|
|
// * To->UniqueSuccessor dominates From
|
|
|
|
// * To->UniqueSuccessor dominates From
|
|
|
|
static bool IsBackEdge(BasicBlock *From, BasicBlock *To,
|
|
|
|
bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT) {
|
|
|
|
const DominatorTree *DT) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (DT->dominates(To, From)) return true;
|
|
|
|
if (DT->dominates(To, From)) return true;
|
|
|
|
if (auto Next = To->getUniqueSuccessor())
|
|
|
|
if (auto Next = To->getUniqueSuccessor())
|
|
|
@ -651,7 +639,7 @@ static bool IsBackEdge(BasicBlock *From, BasicBlock *To,
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Note that Cmp pruning is controlled by the same flag as the
|
|
|
|
// Note that Cmp pruning is controlled by the same flag as the
|
|
|
|
// BB pruning.
|
|
|
|
// BB pruning.
|
|
|
|
static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
|
|
|
|
bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
|
|
|
|
const SanitizerCoverageOptions &Options) {
|
|
|
|
const SanitizerCoverageOptions &Options) {
|
|
|
|
|
|
|
|
|
|
|
|
if (!Options.NoPrune)
|
|
|
|
if (!Options.NoPrune)
|
|
|
@ -1046,7 +1034,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
|
|
|
|
|
|
|
|
|
|
|
if (IsEntryBB) {
|
|
|
|
if (IsEntryBB) {
|
|
|
|
|
|
|
|
|
|
|
|
// Keep static allocas and llvm.localescape calls in the entry block. Even
|
|
|
|
// Keep allocas and llvm.localescape calls in the entry block. Even
|
|
|
|
// if we aren't splitting the block, it's nice for allocas to be before
|
|
|
|
// if we aren't splitting the block, it's nice for allocas to be before
|
|
|
|
// calls.
|
|
|
|
// calls.
|
|
|
|
IP = PrepareToSplitEntryBlock(BB, IP);
|
|
|
|
IP = PrepareToSplitEntryBlock(BB, IP);
|
|
|
@ -1221,7 +1209,7 @@ ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void registerPCGUARDPass(const PassManagerBuilder &,
|
|
|
|
void registerPCGUARDPass(const PassManagerBuilder &,
|
|
|
|
legacy::PassManagerBase &PM) {
|
|
|
|
legacy::PassManagerBase &PM) {
|
|
|
|
|
|
|
|
|
|
|
|
auto p = new ModuleSanitizerCoverageLegacyPass();
|
|
|
|
auto p = new ModuleSanitizerCoverageLegacyPass();
|
|
|
@ -1229,9 +1217,9 @@ static void registerPCGUARDPass(const PassManagerBuilder &,
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static RegisterStandardPasses RegisterCompTransPass(
|
|
|
|
RegisterStandardPasses RegisterCompTransPass(
|
|
|
|
PassManagerBuilder::EP_OptimizerLast, registerPCGUARDPass);
|
|
|
|
PassManagerBuilder::EP_OptimizerLast, registerPCGUARDPass);
|
|
|
|
|
|
|
|
|
|
|
|
static RegisterStandardPasses RegisterCompTransPass0(
|
|
|
|
RegisterStandardPasses RegisterCompTransPass0(
|
|
|
|
PassManagerBuilder::EP_EnabledOnOptLevel0, registerPCGUARDPass);
|
|
|
|
PassManagerBuilder::EP_EnabledOnOptLevel0, registerPCGUARDPass);
|
|
|
|
|
|
|
|
|
|
|
|