Skip to content

Commit

Permalink
[SanitizerCoverage] Create comdat for global arrays.
Browse files Browse the repository at this point in the history
Summary:
Place global arrays in comdat sections with their associated functions.
This makes sure they are stripped along with the functions they
reference, even on the BFD linker.

Reviewers: eugenis

Reviewed By: eugenis

Subscribers: eraman, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D51902

llvm-svn: 341951
  • Loading branch information
morehouse committed Sep 11, 2018
1 parent 873cae5 commit eac270c
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 21 deletions.
45 changes: 31 additions & 14 deletions llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ class SanitizerCoverageModule : public ModulePass {
MDNode::get(*C, None));
}

std::string UniqueSuffix() {
static size_t Count = 0;
return "_sancov" + std::to_string(Count++);
}

std::string getSectionName(const std::string &Section) const;
std::string getSectionStart(const std::string &Section) const;
std::string getSectionEnd(const std::string &Section) const;
Expand Down Expand Up @@ -571,11 +576,34 @@ GlobalVariable *SanitizerCoverageModule::CreateFunctionLocalArrayInSection(
auto Array = new GlobalVariable(
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
Constant::getNullValue(ArrayTy), "__sancov_gen_");
if (auto Comdat = F.getComdat())
if (auto Comdat = F.getComdat()) {
Array->setComdat(Comdat);
} else {
// TODO: Refactor into a helper function and use it in ASan.
assert(F.hasName());
std::string Name = F.getName();
if (F.hasLocalLinkage()) {
std::string ModuleId = getUniqueModuleId(CurModule);
Name += ModuleId.empty() ? UniqueSuffix() : ModuleId;
}
Comdat = CurModule->getOrInsertComdat(Name);
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. Also upgrade private
// linkage to internal linkage so that a symbol table entry is emitted. This
// is necessary in order to create the comdat group.
if (TargetTriple.isOSBinFormatCOFF()) {
Comdat->setSelectionKind(Comdat::NoDuplicates);
if (F.hasPrivateLinkage())
F.setLinkage(GlobalValue::InternalLinkage);
}
F.setComdat(Comdat);
Array->setComdat(Comdat);
}
Array->setSection(getSectionName(Section));
Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize()
: Ty->getPrimitiveSizeInBits() / 8);
GlobalsToAppendToCompilerUsed.push_back(Array);
MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
Array->addMetadata(LLVMContext::MD_associated, *MD);
return Array;
}

Expand Down Expand Up @@ -613,23 +641,12 @@ void SanitizerCoverageModule::CreateFunctionLocalArrays(
FunctionGuardArray = CreateFunctionLocalArrayInSection(
AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName);
GlobalsToAppendToUsed.push_back(FunctionGuardArray);
GlobalsToAppendToCompilerUsed.push_back(FunctionGuardArray);
MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
FunctionGuardArray->addMetadata(LLVMContext::MD_associated, *MD);
}
if (Options.Inline8bitCounters) {
if (Options.Inline8bitCounters)
Function8bitCounterArray = CreateFunctionLocalArrayInSection(
AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName);
GlobalsToAppendToCompilerUsed.push_back(Function8bitCounterArray);
MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
Function8bitCounterArray->addMetadata(LLVMContext::MD_associated, *MD);
}
if (Options.PCTable) {
if (Options.PCTable)
FunctionPCsArray = CreatePCArray(F, AllBlocks);
GlobalsToAppendToCompilerUsed.push_back(FunctionPCsArray);
MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
FunctionPCsArray->addMetadata(LLVMContext::MD_associated, *MD);
}
}

bool SanitizerCoverageModule::InjectCoverage(Function &F,
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Instrumentation/SanitizerCoverage/div-tracing.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ entry:
ret i32 %div
}

; CHECK-LABEL: div_a_b
; CHECK-LABEL: @div_a_b
; CHECK: call void @__sanitizer_cov_trace_div4(i32 %b)
; CHECK: ret

Expand All @@ -21,7 +21,7 @@ entry:
ret i32 %div
}

; CHECK-LABEL: div_a_10
; CHECK-LABEL: @div_a_10
; CHECK-NOT: __sanitizer_cov_trace_div
; CHECK: ret

Expand All @@ -31,7 +31,7 @@ entry:
ret i64 %div
}

; CHECK-LABEL: div_a_b
; CHECK-LABEL: @div_a_b_64
; CHECK: call void @__sanitizer_cov_trace_div8(i64 %b)
; CHECK: ret

2 changes: 1 addition & 1 deletion llvm/test/Instrumentation/SanitizerCoverage/gep-tracing.ll
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ entry:
ret void
}

; CHECK-LABEL: define void @gep_2([1000 x i32]* nocapture %a, i32 %i, i32 %j) {
; CHECK-LABEL: define void @gep_2([1000 x i32]* nocapture %a, i32 %i, i32 %j)
; CHECK: call void @__sanitizer_cov_trace_gep(i64 %idxprom1)
; CHECK: call void @__sanitizer_cov_trace_gep(i64 %idxprom)
; CHECK: ret void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
target triple = "x86_64-unknown-linux-gnu"
define void @foo() {
entry:
; CHECK: section "__sancov_cntrs", align 1
; CHECK: section "__sancov_cntrs", comdat($foo), align 1
; CHECK: %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize
; CHECK: %1 = add i8 %0, 1
; CHECK: store i8 %1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__sancov_gen_, i64 0, i64 0), !nosanitize
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ entry:
ret void
}

; CHECK: private constant [6 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}], section "__sancov_pcs", align 8
; CHECK: private constant [6 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}], section "__sancov_pcs", comdat($foo), align 8
; CHECK: define internal void @sancov.module_ctor
; CHECK: call void @__sanitizer_cov
; CHECK: call void @__sanitizer_cov_pcs_init
2 changes: 1 addition & 1 deletion llvm/test/Instrumentation/SanitizerCoverage/tracing.ll
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ entry:
; CHECK_PC: ret void
; CHECK_PC-NOT: call void @__sanitizer_cov_module_init

; CHECK_PC_GUARD: section "__sancov_guards", align 4
; CHECK_PC_GUARD: section "__sancov_guards", comdat($foo), align 4
; CHECK_PC_GUARD-LABEL: define void @foo
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
Expand Down

0 comments on commit eac270c

Please sign in to comment.