[llvm] [sancov] add -sanitizer-coverage-drop-ctors (PR #137980)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 30 08:33:32 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Alexander Potapenko (ramosian-glider)
<details>
<summary>Changes</summary>
- **[sancov] apply clang-format**
- **[sancov] add -sanitizer-coverage-drop-ctors**
---
Full diff: https://github.com/llvm/llvm-project/pull/137980.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (+58-58)
- (modified) llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard.ll (+7-6)
``````````diff
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 }
``````````
</details>
https://github.com/llvm/llvm-project/pull/137980
More information about the llvm-commits
mailing list