-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[sancov] add -sanitizer-coverage-drop-ctors #137980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[sancov] add -sanitizer-coverage-drop-ctors #137980
Conversation
@llvm/pr-subscribers-compiler-rt-sanitizer @llvm/pr-subscribers-llvm-transforms Author: Alexander Potapenko (ramosian-glider) Changes
Full diff: https://github.com/llvm/llvm-project/pull/137980.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index e52269637b92d..57d96353dd537 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -117,6 +117,11 @@ static cl::opt<bool>
cl::desc("increments 8-bit counter for every edge"),
cl::Hidden);
+static cl::opt<bool>
+ ClSancovDropCtors("sanitizer-coverage-drop-ctors",
+ cl::desc("do not emit module ctors for global counters"),
+ cl::Hidden);
+
static cl::opt<bool>
ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag",
cl::desc("sets a boolean flag for every edge"),
@@ -288,11 +293,11 @@ class ModuleSanitizerCoverage {
LLVMContext *C;
const DataLayout *DL;
- GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
- GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
- GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
- GlobalVariable *FunctionPCsArray; // for pc-table.
- GlobalVariable *FunctionCFsArray; // for control flow table
+ GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
+ GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
+ GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
+ GlobalVariable *FunctionPCsArray; // for pc-table.
+ GlobalVariable *FunctionCFsArray; // for control flow table
SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed;
SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed;
@@ -336,13 +341,11 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF()
? GlobalVariable::ExternalLinkage
: GlobalVariable::ExternalWeakLinkage;
- GlobalVariable *SecStart =
- new GlobalVariable(M, Ty, false, Linkage, nullptr,
- getSectionStart(Section));
+ GlobalVariable *SecStart = new GlobalVariable(M, Ty, false, Linkage, nullptr,
+ getSectionStart(Section));
SecStart->setVisibility(GlobalValue::HiddenVisibility);
- GlobalVariable *SecEnd =
- new GlobalVariable(M, Ty, false, Linkage, nullptr,
- getSectionEnd(Section));
+ GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr,
+ getSectionEnd(Section));
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
IRBuilder<> IRB(M.getContext());
if (!TargetTriple.isOSBinFormatCOFF())
@@ -358,6 +361,8 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
const char *Section) {
+ if (ClSancovDropCtors)
+ return nullptr;
auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
auto SecStart = SecStartEnd.first;
auto SecEnd = SecStartEnd.second;
@@ -447,25 +452,16 @@ bool ModuleSanitizerCoverage::instrumentModule() {
// Loads.
SanCovLoadFunction[0] = M.getOrInsertFunction(SanCovLoad1, VoidTy, PtrTy);
- SanCovLoadFunction[1] =
- M.getOrInsertFunction(SanCovLoad2, VoidTy, PtrTy);
- SanCovLoadFunction[2] =
- M.getOrInsertFunction(SanCovLoad4, VoidTy, PtrTy);
- SanCovLoadFunction[3] =
- M.getOrInsertFunction(SanCovLoad8, VoidTy, PtrTy);
- SanCovLoadFunction[4] =
- M.getOrInsertFunction(SanCovLoad16, VoidTy, PtrTy);
+ SanCovLoadFunction[1] = M.getOrInsertFunction(SanCovLoad2, VoidTy, PtrTy);
+ SanCovLoadFunction[2] = M.getOrInsertFunction(SanCovLoad4, VoidTy, PtrTy);
+ SanCovLoadFunction[3] = M.getOrInsertFunction(SanCovLoad8, VoidTy, PtrTy);
+ SanCovLoadFunction[4] = M.getOrInsertFunction(SanCovLoad16, VoidTy, PtrTy);
// Stores.
- SanCovStoreFunction[0] =
- M.getOrInsertFunction(SanCovStore1, VoidTy, PtrTy);
- SanCovStoreFunction[1] =
- M.getOrInsertFunction(SanCovStore2, VoidTy, PtrTy);
- SanCovStoreFunction[2] =
- M.getOrInsertFunction(SanCovStore4, VoidTy, PtrTy);
- SanCovStoreFunction[3] =
- M.getOrInsertFunction(SanCovStore8, VoidTy, PtrTy);
- SanCovStoreFunction[4] =
- M.getOrInsertFunction(SanCovStore16, VoidTy, PtrTy);
+ SanCovStoreFunction[0] = M.getOrInsertFunction(SanCovStore1, VoidTy, PtrTy);
+ SanCovStoreFunction[1] = M.getOrInsertFunction(SanCovStore2, VoidTy, PtrTy);
+ SanCovStoreFunction[2] = M.getOrInsertFunction(SanCovStore4, VoidTy, PtrTy);
+ SanCovStoreFunction[3] = M.getOrInsertFunction(SanCovStore8, VoidTy, PtrTy);
+ SanCovStoreFunction[4] = M.getOrInsertFunction(SanCovStore16, VoidTy, PtrTy);
{
AttributeList AL;
@@ -534,16 +530,16 @@ bool ModuleSanitizerCoverage::instrumentModule() {
}
if (Ctor && Options.PCTable) {
auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrTy);
- FunctionCallee InitFunction = declareSanitizerInitFunction(
- M, SanCovPCsInitName, {PtrTy, PtrTy});
+ FunctionCallee InitFunction =
+ declareSanitizerInitFunction(M, SanCovPCsInitName, {PtrTy, PtrTy});
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
}
if (Ctor && Options.CollectControlFlow) {
auto SecStartEnd = CreateSecStartEnd(M, SanCovCFsSectionName, IntptrTy);
- FunctionCallee InitFunction = declareSanitizerInitFunction(
- M, SanCovCFsInitName, {PtrTy, PtrTy});
+ FunctionCallee InitFunction =
+ declareSanitizerInitFunction(M, SanCovCFsInitName, {PtrTy, PtrTy});
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
}
@@ -600,8 +596,8 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
// Do not instrument full dominators, or full post-dominators with multiple
// predecessors.
- return !isFullDominator(BB, DT)
- && !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
+ return !isFullDominator(BB, DT) &&
+ !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
}
// Returns true iff From->To is a backedge.
@@ -776,16 +772,16 @@ ModuleSanitizerCoverage::CreatePCArray(Function &F,
for (size_t i = 0; i < N; i++) {
if (&F.getEntryBlock() == AllBlocks[i]) {
PCs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy));
- PCs.push_back((Constant *)IRB.CreateIntToPtr(
- ConstantInt::get(IntptrTy, 1), PtrTy));
+ PCs.push_back(
+ (Constant *)IRB.CreateIntToPtr(ConstantInt::get(IntptrTy, 1), PtrTy));
} else {
PCs.push_back((Constant *)IRB.CreatePointerCast(
BlockAddress::get(AllBlocks[i]), PtrTy));
PCs.push_back(Constant::getNullValue(PtrTy));
}
}
- auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, PtrTy,
- SanCovPCsSectionName);
+ auto *PCArray =
+ CreateFunctionLocalArrayInSection(N * 2, F, PtrTy, SanCovPCsSectionName);
PCArray->setInitializer(
ConstantArray::get(ArrayType::get(PtrTy, N * 2), PCs));
PCArray->setConstant(true);
@@ -840,7 +836,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function &F,
ArrayRef<BasicBlock *> AllBlocks,
Value *&FunctionGateCmp,
bool IsLeafFunc) {
- if (AllBlocks.empty()) return false;
+ if (AllBlocks.empty())
+ return false;
CreateFunctionLocalArrays(F, AllBlocks);
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
InjectCoverageAtBlock(F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
@@ -923,13 +920,14 @@ void ModuleSanitizerCoverage::InjectTraceForDiv(
for (auto *BO : DivTraceTargets) {
InstrumentationIRBuilder IRB(BO);
Value *A1 = BO->getOperand(1);
- if (isa<ConstantInt>(A1)) continue;
+ if (isa<ConstantInt>(A1))
+ continue;
if (!A1->getType()->isIntegerTy())
continue;
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
- int CallbackIdx = TypeSize == 32 ? 0 :
- TypeSize == 64 ? 1 : -1;
- if (CallbackIdx < 0) continue;
+ int CallbackIdx = TypeSize == 32 ? 0 : TypeSize == 64 ? 1 : -1;
+ if (CallbackIdx < 0)
+ continue;
auto Ty = Type::getIntNTy(*C, TypeSize);
IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
{IRB.CreateIntCast(A1, Ty, true)});
@@ -987,17 +985,20 @@ void ModuleSanitizerCoverage::InjectTraceForCmp(
if (!A0->getType()->isIntegerTy())
continue;
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
- int CallbackIdx = TypeSize == 8 ? 0 :
- TypeSize == 16 ? 1 :
- TypeSize == 32 ? 2 :
- TypeSize == 64 ? 3 : -1;
- if (CallbackIdx < 0) continue;
+ int CallbackIdx = TypeSize == 8 ? 0
+ : TypeSize == 16 ? 1
+ : TypeSize == 32 ? 2
+ : TypeSize == 64 ? 3
+ : -1;
+ if (CallbackIdx < 0)
+ continue;
// __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
bool FirstIsConst = isa<ConstantInt>(A0);
bool SecondIsConst = isa<ConstantInt>(A1);
// If both are const, then we don't need such a comparison.
- if (FirstIsConst && SecondIsConst) continue;
+ if (FirstIsConst && SecondIsConst)
+ continue;
// If only one is const, then make it the first callback argument.
if (FirstIsConst || SecondIsConst) {
CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
@@ -1136,13 +1137,13 @@ void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) {
if (&BB == &F.getEntryBlock())
CFs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy));
else
- CFs.push_back((Constant *)IRB.CreatePointerCast(BlockAddress::get(&BB),
- PtrTy));
+ CFs.push_back(
+ (Constant *)IRB.CreatePointerCast(BlockAddress::get(&BB), PtrTy));
for (auto SuccBB : successors(&BB)) {
assert(SuccBB != &F.getEntryBlock());
- CFs.push_back((Constant *)IRB.CreatePointerCast(BlockAddress::get(SuccBB),
- PtrTy));
+ CFs.push_back(
+ (Constant *)IRB.CreatePointerCast(BlockAddress::get(SuccBB), PtrTy));
}
CFs.push_back((Constant *)Constant::getNullValue(PtrTy));
@@ -1156,8 +1157,7 @@ void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) {
} else {
auto CalledF = CB->getCalledFunction();
if (CalledF && !CalledF->isIntrinsic())
- CFs.push_back(
- (Constant *)IRB.CreatePointerCast(CalledF, PtrTy));
+ CFs.push_back((Constant *)IRB.CreatePointerCast(CalledF, PtrTy));
}
}
}
@@ -1165,8 +1165,8 @@ void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) {
CFs.push_back((Constant *)Constant::getNullValue(PtrTy));
}
- FunctionCFsArray = CreateFunctionLocalArrayInSection(
- CFs.size(), F, PtrTy, SanCovCFsSectionName);
+ FunctionCFsArray = CreateFunctionLocalArrayInSection(CFs.size(), F, PtrTy,
+ SanCovCFsSectionName);
FunctionCFsArray->setInitializer(
ConstantArray::get(ArrayType::get(PtrTy, CFs.size()), CFs));
FunctionCFsArray->setConstant(true);
diff --git a/llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard.ll b/llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard.ll
index 5deb74eb8c6aa..5d46c23058b8e 100644
--- a/llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard.ll
+++ b/llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard.ll
@@ -1,8 +1,9 @@
-; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=x86_64 -S | FileCheck %s --check-prefixes=CHECK,COMDAT,ELF
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=x86_64 -S | FileCheck %s --check-prefixes=CHECK,CHECK-CTOR,COMDAT,ELF,ELF-CTOR
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-drop-ctors=1 -mtriple=x86_64 -S | FileCheck %s --check-prefixes=CHECK,COMDAT,ELF
-; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=aarch64-apple-darwin -S | FileCheck %s --check-prefixes=CHECK,MACHO
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=aarch64-apple-darwin -S | FileCheck %s --check-prefixes=CHECK,CHECK-CTOR,MACHO
-; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=x86_64-windows -S | FileCheck %s --check-prefixes=CHECK,COMDAT,WIN
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -mtriple=x86_64-windows -S | FileCheck %s --check-prefixes=CHECK,CHECK-CTOR,COMDAT,WIN
; COMDAT: $foo = comdat nodeduplicate
; COMDAT: $CallViaVptr = comdat nodeduplicate
@@ -20,7 +21,7 @@
; WIN-NEXT: @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, section ".SCOV$GM", comdat($CallViaVptr), align 4{{$}}
; WIN-NEXT: @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, section ".SCOV$GM", comdat($DirectBitcastCall), align 4{{$}}
-; ELF: @llvm.used = appending global [1 x ptr] [ptr @sancov.module_ctor_trace_pc_guard]
+; ELF-CTOR: @llvm.used = appending global [1 x ptr] [ptr @sancov.module_ctor_trace_pc_guard]
; ELF: @llvm.compiler.used = appending global [3 x ptr] [ptr @__sancov_gen_, ptr @__sancov_gen_.1, ptr @__sancov_gen_.2], section "llvm.metadata"
; MACHO: @llvm.used = appending global [4 x ptr] [ptr @sancov.module_ctor_trace_pc_guard, ptr @__sancov_gen_, ptr @__sancov_gen_.1, ptr @__sancov_gen_.2]
; MACHO-NOT: @llvm.compiler.used =
@@ -73,7 +74,7 @@ define void @DirectBitcastCall() sanitize_address {
ret void
}
-; ELF-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 comdat {
+; ELF-CTOR-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 comdat {
; MACHO-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 {
-; CHECK: attributes #2 = { nounwind }
+; CHECK-CTOR: attributes #2 = { nounwind }
|
The current description is
you want to change it to the final commit message and state the motivation to add the option. |
Oh, I didn't realize the patches will be squashed. Let me update the description then. |
Add a hidden flag to omit the @sancov.module_ctor* constructors. When building kernel modules with sanitizer coverage enabled, constructors may reference global symbols, creating unsupported relocations. Because the kernel does not strictly need these constructors in order for coverage to work, allow the user to omit them. Also apply clang-format to SanitizerCoverage.cpp. Fixes PR132393.
55a2ce9
to
1ac6e55
Compare
I updated the initial comment to match the new description just for the case. |
[sancov] add -sanitizer-coverage-drop-ctors
Add a hidden flag to omit the @sancov.module_ctor* constructors.
When building kernel modules with sanitizer coverage enabled,
constructors may reference global symbols, creating unsupported
relocations. Because the kernel does not strictly need these
constructors in order for coverage to work, allow the user to omit
them.
Also apply clang-format to SanitizerCoverage.cpp.
Fixes PR132393.