mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-03 00:01:39 +00:00
[sanitizer-coverage] refactor the code to make it easier to add more sections in future. NFC
llvm-svn: 304610
This commit is contained in:
parent
3c03fadd49
commit
f507eff18c
@ -58,6 +58,8 @@ static const char *const SanCovTracePCGuardName =
|
||||
static const char *const SanCovTracePCGuardInitName =
|
||||
"__sanitizer_cov_trace_pc_guard_init";
|
||||
|
||||
static const char *const SanCovGuardsSectionName = "sancov_guards";
|
||||
|
||||
static cl::opt<int> ClCoverageLevel(
|
||||
"sanitizer-coverage-level",
|
||||
cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
|
||||
@ -159,11 +161,17 @@ private:
|
||||
void InjectTraceForSwitch(Function &F,
|
||||
ArrayRef<Instruction *> SwitchTraceTargets);
|
||||
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
||||
void CreateFunctionGuardArray(size_t NumGuards, Function &F);
|
||||
GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements,
|
||||
Function &F, Type *Ty,
|
||||
const char *Section);
|
||||
void CreateFunctionLocalArrays(size_t NumGuards, Function &F);
|
||||
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx);
|
||||
StringRef getSanCovTracePCGuardSection() const;
|
||||
StringRef getSanCovTracePCGuardSectionStart() const;
|
||||
StringRef getSanCovTracePCGuardSectionEnd() const;
|
||||
void CreateInitCallForSection(Module &M, const char *InitFunctionName,
|
||||
Type *Ty, const std::string &Section);
|
||||
|
||||
std::string getSectionName(const std::string &Section) const;
|
||||
std::string getSectionStart(const std::string &Section) const;
|
||||
std::string getSectionEnd(const std::string &Section) const;
|
||||
Function *SanCovTracePCIndir;
|
||||
Function *SanCovTracePC, *SanCovTracePCGuard;
|
||||
Function *SanCovTraceCmpFunction[4];
|
||||
@ -178,13 +186,39 @@ private:
|
||||
const DataLayout *DL;
|
||||
|
||||
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
|
||||
bool HasSancovGuardsSection;
|
||||
|
||||
SanitizerCoverageOptions Options;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void SanitizerCoverageModule::CreateInitCallForSection(
|
||||
Module &M, const char *InitFunctionName, Type *Ty,
|
||||
const std::string &Section) {
|
||||
IRBuilder<> IRB(M.getContext());
|
||||
Function *CtorFunc;
|
||||
GlobalVariable *SecStart =
|
||||
new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr,
|
||||
getSectionStart(Section));
|
||||
SecStart->setVisibility(GlobalValue::HiddenVisibility);
|
||||
GlobalVariable *SecEnd =
|
||||
new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
|
||||
nullptr, getSectionEnd(Section));
|
||||
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
|
||||
|
||||
std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
|
||||
M, SanCovModuleCtorName, InitFunctionName, {Ty, Ty},
|
||||
{IRB.CreatePointerCast(SecStart, Ty), IRB.CreatePointerCast(SecEnd, Ty)});
|
||||
|
||||
if (TargetTriple.supportsCOMDAT()) {
|
||||
// Use comdat to dedup CtorFunc.
|
||||
CtorFunc->setComdat(M.getOrInsertComdat(SanCovModuleCtorName));
|
||||
appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc);
|
||||
} else {
|
||||
appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
|
||||
}
|
||||
}
|
||||
|
||||
bool SanitizerCoverageModule::runOnModule(Module &M) {
|
||||
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
|
||||
return false;
|
||||
@ -192,7 +226,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
||||
DL = &M.getDataLayout();
|
||||
CurModule = &M;
|
||||
TargetTriple = Triple(M.getTargetTriple());
|
||||
HasSancovGuardsSection = false;
|
||||
FunctionGuardArray = nullptr;
|
||||
IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
|
||||
IntptrPtrTy = PointerType::getUnqual(IntptrTy);
|
||||
Type *VoidTy = Type::getVoidTy(*C);
|
||||
@ -243,34 +277,10 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
||||
for (auto &F : M)
|
||||
runOnFunction(F);
|
||||
|
||||
// Create variable for module (compilation unit) name
|
||||
if (Options.TracePCGuard) {
|
||||
if (HasSancovGuardsSection) {
|
||||
Function *CtorFunc;
|
||||
GlobalVariable *SecStart = new GlobalVariable(
|
||||
M, Int32PtrTy, false, GlobalVariable::ExternalLinkage, nullptr,
|
||||
getSanCovTracePCGuardSectionStart());
|
||||
SecStart->setVisibility(GlobalValue::HiddenVisibility);
|
||||
GlobalVariable *SecEnd = new GlobalVariable(
|
||||
M, Int32PtrTy, false, GlobalVariable::ExternalLinkage, nullptr,
|
||||
getSanCovTracePCGuardSectionEnd());
|
||||
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
|
||||
if (FunctionGuardArray)
|
||||
CreateInitCallForSection(M, SanCovTracePCGuardInitName, Int32PtrTy,
|
||||
SanCovGuardsSectionName);
|
||||
|
||||
std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
|
||||
M, SanCovModuleCtorName, SanCovTracePCGuardInitName,
|
||||
{Int32PtrTy, Int32PtrTy},
|
||||
{IRB.CreatePointerCast(SecStart, Int32PtrTy),
|
||||
IRB.CreatePointerCast(SecEnd, Int32PtrTy)});
|
||||
|
||||
if (TargetTriple.supportsCOMDAT()) {
|
||||
// Use comdat to dedup CtorFunc.
|
||||
CtorFunc->setComdat(M.getOrInsertComdat(SanCovModuleCtorName));
|
||||
appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc);
|
||||
} else {
|
||||
appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -393,17 +403,23 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
|
||||
InjectTraceForGep(F, GepTraceTargets);
|
||||
return true;
|
||||
}
|
||||
void SanitizerCoverageModule::CreateFunctionGuardArray(size_t NumGuards,
|
||||
Function &F) {
|
||||
if (!Options.TracePCGuard) return;
|
||||
HasSancovGuardsSection = true;
|
||||
ArrayType *ArrayOfInt32Ty = ArrayType::get(Int32Ty, NumGuards);
|
||||
FunctionGuardArray = new GlobalVariable(
|
||||
*CurModule, ArrayOfInt32Ty, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayOfInt32Ty), "__sancov_gen_");
|
||||
|
||||
GlobalVariable *SanitizerCoverageModule::CreateFunctionLocalArrayInSection(
|
||||
size_t NumElements, Function &F, Type *Ty, const char *Section) {
|
||||
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
|
||||
auto Array = new GlobalVariable(
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
if (auto Comdat = F.getComdat())
|
||||
FunctionGuardArray->setComdat(Comdat);
|
||||
FunctionGuardArray->setSection(getSanCovTracePCGuardSection());
|
||||
Array->setComdat(Comdat);
|
||||
Array->setSection(getSectionName(Section));
|
||||
return Array;
|
||||
}
|
||||
void SanitizerCoverageModule::CreateFunctionLocalArrays(size_t NumGuards,
|
||||
Function &F) {
|
||||
if (Options.TracePCGuard)
|
||||
FunctionGuardArray = CreateFunctionLocalArrayInSection(
|
||||
NumGuards, F, Int32Ty, SanCovGuardsSectionName);
|
||||
}
|
||||
|
||||
bool SanitizerCoverageModule::InjectCoverage(Function &F,
|
||||
@ -413,11 +429,11 @@ bool SanitizerCoverageModule::InjectCoverage(Function &F,
|
||||
case SanitizerCoverageOptions::SCK_None:
|
||||
return false;
|
||||
case SanitizerCoverageOptions::SCK_Function:
|
||||
CreateFunctionGuardArray(1, F);
|
||||
CreateFunctionLocalArrays(1, F);
|
||||
InjectCoverageAtBlock(F, F.getEntryBlock(), 0);
|
||||
return true;
|
||||
default: {
|
||||
CreateFunctionGuardArray(AllBlocks.size(), F);
|
||||
CreateFunctionLocalArrays(AllBlocks.size(), F);
|
||||
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
|
||||
InjectCoverageAtBlock(F, *AllBlocks[i], i);
|
||||
return true;
|
||||
@ -575,24 +591,27 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
||||
}
|
||||
}
|
||||
|
||||
StringRef SanitizerCoverageModule::getSanCovTracePCGuardSection() const {
|
||||
std::string
|
||||
SanitizerCoverageModule::getSectionName(const std::string &Section) const {
|
||||
if (TargetTriple.getObjectFormat() == Triple::COFF)
|
||||
return ".SCOV$M";
|
||||
if (TargetTriple.isOSBinFormatMachO())
|
||||
return "__DATA,__sancov_guards";
|
||||
return "__sancov_guards";
|
||||
return "__DATA,__" + Section;
|
||||
return "__" + Section;
|
||||
}
|
||||
|
||||
StringRef SanitizerCoverageModule::getSanCovTracePCGuardSectionStart() const {
|
||||
std::string
|
||||
SanitizerCoverageModule::getSectionStart(const std::string &Section) const {
|
||||
if (TargetTriple.isOSBinFormatMachO())
|
||||
return "\1section$start$__DATA$__sancov_guards";
|
||||
return "__start___sancov_guards";
|
||||
return "\1section$start$__DATA$__" + Section;
|
||||
return "__start___" + Section;
|
||||
}
|
||||
|
||||
StringRef SanitizerCoverageModule::getSanCovTracePCGuardSectionEnd() const {
|
||||
std::string
|
||||
SanitizerCoverageModule::getSectionEnd(const std::string &Section) const {
|
||||
if (TargetTriple.isOSBinFormatMachO())
|
||||
return "\1section$end$__DATA$__sancov_guards";
|
||||
return "__stop___sancov_guards";
|
||||
return "\1section$end$__DATA$__" + Section;
|
||||
return "__stop___" + Section;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user