Skip to content

Commit 9732427

Browse files
[sancov] add -sanitizer-coverage-drop-ctors (#137980)
[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.
1 parent 09d01be commit 9732427

File tree

2 files changed

+65
-64
lines changed

2 files changed

+65
-64
lines changed

llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ static cl::opt<bool>
118118
cl::desc("increments 8-bit counter for every edge"),
119119
cl::Hidden);
120120

121+
static cl::opt<bool>
122+
ClSancovDropCtors("sanitizer-coverage-drop-ctors",
123+
cl::desc("do not emit module ctors for global counters"),
124+
cl::Hidden);
125+
121126
static cl::opt<bool>
122127
ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag",
123128
cl::desc("sets a boolean flag for every edge"),
@@ -298,11 +303,11 @@ class ModuleSanitizerCoverage {
298303
LLVMContext *C;
299304
const DataLayout *DL;
300305

301-
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
302-
GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
303-
GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
304-
GlobalVariable *FunctionPCsArray; // for pc-table.
305-
GlobalVariable *FunctionCFsArray; // for control flow table
306+
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
307+
GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
308+
GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
309+
GlobalVariable *FunctionPCsArray; // for pc-table.
310+
GlobalVariable *FunctionCFsArray; // for control flow table
306311
SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed;
307312
SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed;
308313

@@ -346,13 +351,11 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
346351
GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF()
347352
? GlobalVariable::ExternalLinkage
348353
: GlobalVariable::ExternalWeakLinkage;
349-
GlobalVariable *SecStart =
350-
new GlobalVariable(M, Ty, false, Linkage, nullptr,
351-
getSectionStart(Section));
354+
GlobalVariable *SecStart = new GlobalVariable(M, Ty, false, Linkage, nullptr,
355+
getSectionStart(Section));
352356
SecStart->setVisibility(GlobalValue::HiddenVisibility);
353-
GlobalVariable *SecEnd =
354-
new GlobalVariable(M, Ty, false, Linkage, nullptr,
355-
getSectionEnd(Section));
357+
GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr,
358+
getSectionEnd(Section));
356359
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
357360
IRBuilder<> IRB(M.getContext());
358361
if (!TargetTriple.isOSBinFormatCOFF())
@@ -368,6 +371,8 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
368371
Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
369372
Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
370373
const char *Section) {
374+
if (ClSancovDropCtors)
375+
return nullptr;
371376
auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
372377
auto SecStart = SecStartEnd.first;
373378
auto SecEnd = SecStartEnd.second;
@@ -457,25 +462,16 @@ bool ModuleSanitizerCoverage::instrumentModule() {
457462

458463
// Loads.
459464
SanCovLoadFunction[0] = M.getOrInsertFunction(SanCovLoad1, VoidTy, PtrTy);
460-
SanCovLoadFunction[1] =
461-
M.getOrInsertFunction(SanCovLoad2, VoidTy, PtrTy);
462-
SanCovLoadFunction[2] =
463-
M.getOrInsertFunction(SanCovLoad4, VoidTy, PtrTy);
464-
SanCovLoadFunction[3] =
465-
M.getOrInsertFunction(SanCovLoad8, VoidTy, PtrTy);
466-
SanCovLoadFunction[4] =
467-
M.getOrInsertFunction(SanCovLoad16, VoidTy, PtrTy);
465+
SanCovLoadFunction[1] = M.getOrInsertFunction(SanCovLoad2, VoidTy, PtrTy);
466+
SanCovLoadFunction[2] = M.getOrInsertFunction(SanCovLoad4, VoidTy, PtrTy);
467+
SanCovLoadFunction[3] = M.getOrInsertFunction(SanCovLoad8, VoidTy, PtrTy);
468+
SanCovLoadFunction[4] = M.getOrInsertFunction(SanCovLoad16, VoidTy, PtrTy);
468469
// Stores.
469-
SanCovStoreFunction[0] =
470-
M.getOrInsertFunction(SanCovStore1, VoidTy, PtrTy);
471-
SanCovStoreFunction[1] =
472-
M.getOrInsertFunction(SanCovStore2, VoidTy, PtrTy);
473-
SanCovStoreFunction[2] =
474-
M.getOrInsertFunction(SanCovStore4, VoidTy, PtrTy);
475-
SanCovStoreFunction[3] =
476-
M.getOrInsertFunction(SanCovStore8, VoidTy, PtrTy);
477-
SanCovStoreFunction[4] =
478-
M.getOrInsertFunction(SanCovStore16, VoidTy, PtrTy);
470+
SanCovStoreFunction[0] = M.getOrInsertFunction(SanCovStore1, VoidTy, PtrTy);
471+
SanCovStoreFunction[1] = M.getOrInsertFunction(SanCovStore2, VoidTy, PtrTy);
472+
SanCovStoreFunction[2] = M.getOrInsertFunction(SanCovStore4, VoidTy, PtrTy);
473+
SanCovStoreFunction[3] = M.getOrInsertFunction(SanCovStore8, VoidTy, PtrTy);
474+
SanCovStoreFunction[4] = M.getOrInsertFunction(SanCovStore16, VoidTy, PtrTy);
479475

480476
{
481477
AttributeList AL;
@@ -547,16 +543,16 @@ bool ModuleSanitizerCoverage::instrumentModule() {
547543
}
548544
if (Ctor && Options.PCTable) {
549545
auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrTy);
550-
FunctionCallee InitFunction = declareSanitizerInitFunction(
551-
M, SanCovPCsInitName, {PtrTy, PtrTy});
546+
FunctionCallee InitFunction =
547+
declareSanitizerInitFunction(M, SanCovPCsInitName, {PtrTy, PtrTy});
552548
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
553549
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
554550
}
555551

556552
if (Ctor && Options.CollectControlFlow) {
557553
auto SecStartEnd = CreateSecStartEnd(M, SanCovCFsSectionName, IntptrTy);
558-
FunctionCallee InitFunction = declareSanitizerInitFunction(
559-
M, SanCovCFsInitName, {PtrTy, PtrTy});
554+
FunctionCallee InitFunction =
555+
declareSanitizerInitFunction(M, SanCovCFsInitName, {PtrTy, PtrTy});
560556
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
561557
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
562558
}
@@ -613,8 +609,8 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
613609

614610
// Do not instrument full dominators, or full post-dominators with multiple
615611
// predecessors.
616-
return !isFullDominator(BB, DT)
617-
&& !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
612+
return !isFullDominator(BB, DT) &&
613+
!(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
618614
}
619615

620616
// Returns true iff From->To is a backedge.
@@ -789,16 +785,16 @@ ModuleSanitizerCoverage::CreatePCArray(Function &F,
789785
for (size_t i = 0; i < N; i++) {
790786
if (&F.getEntryBlock() == AllBlocks[i]) {
791787
PCs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy));
792-
PCs.push_back((Constant *)IRB.CreateIntToPtr(
793-
ConstantInt::get(IntptrTy, 1), PtrTy));
788+
PCs.push_back(
789+
(Constant *)IRB.CreateIntToPtr(ConstantInt::get(IntptrTy, 1), PtrTy));
794790
} else {
795791
PCs.push_back((Constant *)IRB.CreatePointerCast(
796792
BlockAddress::get(AllBlocks[i]), PtrTy));
797793
PCs.push_back(Constant::getNullValue(PtrTy));
798794
}
799795
}
800-
auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, PtrTy,
801-
SanCovPCsSectionName);
796+
auto *PCArray =
797+
CreateFunctionLocalArrayInSection(N * 2, F, PtrTy, SanCovPCsSectionName);
802798
PCArray->setInitializer(
803799
ConstantArray::get(ArrayType::get(PtrTy, N * 2), PCs));
804800
PCArray->setConstant(true);
@@ -853,7 +849,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function &F,
853849
ArrayRef<BasicBlock *> AllBlocks,
854850
Value *&FunctionGateCmp,
855851
bool IsLeafFunc) {
856-
if (AllBlocks.empty()) return false;
852+
if (AllBlocks.empty())
853+
return false;
857854
CreateFunctionLocalArrays(F, AllBlocks);
858855
for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
859856
InjectCoverageAtBlock(F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
@@ -936,13 +933,14 @@ void ModuleSanitizerCoverage::InjectTraceForDiv(
936933
for (auto *BO : DivTraceTargets) {
937934
InstrumentationIRBuilder IRB(BO);
938935
Value *A1 = BO->getOperand(1);
939-
if (isa<ConstantInt>(A1)) continue;
936+
if (isa<ConstantInt>(A1))
937+
continue;
940938
if (!A1->getType()->isIntegerTy())
941939
continue;
942940
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
943-
int CallbackIdx = TypeSize == 32 ? 0 :
944-
TypeSize == 64 ? 1 : -1;
945-
if (CallbackIdx < 0) continue;
941+
int CallbackIdx = TypeSize == 32 ? 0 : TypeSize == 64 ? 1 : -1;
942+
if (CallbackIdx < 0)
943+
continue;
946944
auto Ty = Type::getIntNTy(*C, TypeSize);
947945
IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
948946
{IRB.CreateIntCast(A1, Ty, true)});
@@ -1000,17 +998,20 @@ void ModuleSanitizerCoverage::InjectTraceForCmp(
1000998
if (!A0->getType()->isIntegerTy())
1001999
continue;
10021000
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
1003-
int CallbackIdx = TypeSize == 8 ? 0 :
1004-
TypeSize == 16 ? 1 :
1005-
TypeSize == 32 ? 2 :
1006-
TypeSize == 64 ? 3 : -1;
1007-
if (CallbackIdx < 0) continue;
1001+
int CallbackIdx = TypeSize == 8 ? 0
1002+
: TypeSize == 16 ? 1
1003+
: TypeSize == 32 ? 2
1004+
: TypeSize == 64 ? 3
1005+
: -1;
1006+
if (CallbackIdx < 0)
1007+
continue;
10081008
// __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
10091009
auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
10101010
bool FirstIsConst = isa<ConstantInt>(A0);
10111011
bool SecondIsConst = isa<ConstantInt>(A1);
10121012
// If both are const, then we don't need such a comparison.
1013-
if (FirstIsConst && SecondIsConst) continue;
1013+
if (FirstIsConst && SecondIsConst)
1014+
continue;
10141015
// If only one is const, then make it the first callback argument.
10151016
if (FirstIsConst || SecondIsConst) {
10161017
CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
@@ -1192,13 +1193,13 @@ void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) {
11921193
if (&BB == &F.getEntryBlock())
11931194
CFs.push_back((Constant *)IRB.CreatePointerCast(&F, PtrTy));
11941195
else
1195-
CFs.push_back((Constant *)IRB.CreatePointerCast(BlockAddress::get(&BB),
1196-
PtrTy));
1196+
CFs.push_back(
1197+
(Constant *)IRB.CreatePointerCast(BlockAddress::get(&BB), PtrTy));
11971198

11981199
for (auto SuccBB : successors(&BB)) {
11991200
assert(SuccBB != &F.getEntryBlock());
1200-
CFs.push_back((Constant *)IRB.CreatePointerCast(BlockAddress::get(SuccBB),
1201-
PtrTy));
1201+
CFs.push_back(
1202+
(Constant *)IRB.CreatePointerCast(BlockAddress::get(SuccBB), PtrTy));
12021203
}
12031204

12041205
CFs.push_back((Constant *)Constant::getNullValue(PtrTy));
@@ -1212,17 +1213,16 @@ void ModuleSanitizerCoverage::createFunctionControlFlow(Function &F) {
12121213
} else {
12131214
auto CalledF = CB->getCalledFunction();
12141215
if (CalledF && !CalledF->isIntrinsic())
1215-
CFs.push_back(
1216-
(Constant *)IRB.CreatePointerCast(CalledF, PtrTy));
1216+
CFs.push_back((Constant *)IRB.CreatePointerCast(CalledF, PtrTy));
12171217
}
12181218
}
12191219
}
12201220

12211221
CFs.push_back((Constant *)Constant::getNullValue(PtrTy));
12221222
}
12231223

1224-
FunctionCFsArray = CreateFunctionLocalArrayInSection(
1225-
CFs.size(), F, PtrTy, SanCovCFsSectionName);
1224+
FunctionCFsArray = CreateFunctionLocalArrayInSection(CFs.size(), F, PtrTy,
1225+
SanCovCFsSectionName);
12261226
FunctionCFsArray->setInitializer(
12271227
ConstantArray::get(ArrayType::get(PtrTy, CFs.size()), CFs));
12281228
FunctionCFsArray->setConstant(true);

llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard.ll

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
; 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
1+
; 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
2+
; 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
23

3-
; 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
4+
; 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
45

5-
; 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
6+
; 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
67

78
; COMDAT: $foo = comdat nodeduplicate
89
; COMDAT: $CallViaVptr = comdat nodeduplicate
@@ -20,7 +21,7 @@
2021
; WIN-NEXT: @__sancov_gen_.1 = private global [1 x i32] zeroinitializer, section ".SCOV$GM", comdat($CallViaVptr), align 4{{$}}
2122
; WIN-NEXT: @__sancov_gen_.2 = private global [1 x i32] zeroinitializer, section ".SCOV$GM", comdat($DirectBitcastCall), align 4{{$}}
2223

23-
; ELF: @llvm.used = appending global [1 x ptr] [ptr @sancov.module_ctor_trace_pc_guard]
24+
; ELF-CTOR: @llvm.used = appending global [1 x ptr] [ptr @sancov.module_ctor_trace_pc_guard]
2425
; ELF: @llvm.compiler.used = appending global [3 x ptr] [ptr @__sancov_gen_, ptr @__sancov_gen_.1, ptr @__sancov_gen_.2], section "llvm.metadata"
2526
; 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]
2627
; MACHO-NOT: @llvm.compiler.used =
@@ -73,7 +74,7 @@ define void @DirectBitcastCall() sanitize_address {
7374
ret void
7475
}
7576

76-
; ELF-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 comdat {
77+
; ELF-CTOR-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 comdat {
7778
; MACHO-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 {
7879

79-
; CHECK: attributes #2 = { nounwind }
80+
; CHECK-CTOR: attributes #2 = { nounwind }

0 commit comments

Comments
 (0)