forked from OSchip/llvm-project
Reland the "[NewPM] Port Sancov" patch from rL365838. No functional
changes were made to the patch since then. -------- [NewPM] Port Sancov This patch contains a port of SanitizerCoverage to the new pass manager. This one's a bit hefty. Changes: - Split SanitizerCoverageModule into 2 SanitizerCoverage for passing over functions and ModuleSanitizerCoverage for passing over modules. - ModuleSanitizerCoverage exists for adding 2 module level calls to initialization functions but only if there's a function that was instrumented by sancov. - Added legacy and new PM wrapper classes that own instances of the 2 new classes. - Update llvm tests and add clang tests. llvm-svn: 367053
This commit is contained in:
parent
9294c87282
commit
007f674c6a
|
@ -60,6 +60,7 @@
|
||||||
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
|
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
|
||||||
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
|
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
|
||||||
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
||||||
|
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
|
||||||
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
||||||
#include "llvm/Transforms/ObjCARC.h"
|
#include "llvm/Transforms/ObjCARC.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
|
@ -195,11 +196,8 @@ static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
|
||||||
PM.add(createBoundsCheckingLegacyPass());
|
PM.add(createBoundsCheckingLegacyPass());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
|
static SanitizerCoverageOptions
|
||||||
legacy::PassManagerBase &PM) {
|
getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts) {
|
||||||
const PassManagerBuilderWrapper &BuilderWrapper =
|
|
||||||
static_cast<const PassManagerBuilderWrapper&>(Builder);
|
|
||||||
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
|
|
||||||
SanitizerCoverageOptions Opts;
|
SanitizerCoverageOptions Opts;
|
||||||
Opts.CoverageType =
|
Opts.CoverageType =
|
||||||
static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType);
|
static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType);
|
||||||
|
@ -215,7 +213,17 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
|
||||||
Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
|
Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
|
||||||
Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
|
Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
|
||||||
Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
|
Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
|
||||||
PM.add(createSanitizerCoverageModulePass(Opts));
|
return Opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
|
||||||
|
legacy::PassManagerBase &PM) {
|
||||||
|
const PassManagerBuilderWrapper &BuilderWrapper =
|
||||||
|
static_cast<const PassManagerBuilderWrapper &>(Builder);
|
||||||
|
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
|
||||||
|
auto Opts = getSancovOptsFromCGOpts(CGOpts);
|
||||||
|
PM.add(createModuleSanitizerCoverageLegacyPassPass(Opts));
|
||||||
|
PM.add(createSanitizerCoverageLegacyPassPass(Opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if ASan should use GC-friendly instrumentation for globals.
|
// Check if ASan should use GC-friendly instrumentation for globals.
|
||||||
|
@ -1128,6 +1136,21 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
|
||||||
EntryExitInstrumenterPass(/*PostInlining=*/false)));
|
EntryExitInstrumenterPass(/*PostInlining=*/false)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (CodeGenOpts.SanitizeCoverageType ||
|
||||||
|
CodeGenOpts.SanitizeCoverageIndirectCalls ||
|
||||||
|
CodeGenOpts.SanitizeCoverageTraceCmp) {
|
||||||
|
auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
|
||||||
|
PB.registerPipelineStartEPCallback(
|
||||||
|
[SancovOpts](ModulePassManager &MPM) {
|
||||||
|
MPM.addPass(ModuleSanitizerCoveragePass(SancovOpts));
|
||||||
|
});
|
||||||
|
PB.registerOptimizerLastEPCallback(
|
||||||
|
[SancovOpts](FunctionPassManager &FPM,
|
||||||
|
PassBuilder::OptimizationLevel Level) {
|
||||||
|
FPM.addPass(SanitizerCoveragePass(SancovOpts));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Register callbacks to schedule sanitizer passes at the appropriate part of
|
// Register callbacks to schedule sanitizer passes at the appropriate part of
|
||||||
// the pipeline.
|
// the pipeline.
|
||||||
// FIXME: either handle asan/the remaining sanitizers or error out
|
// FIXME: either handle asan/the remaining sanitizers or error out
|
||||||
|
@ -1205,9 +1228,19 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
|
||||||
/*CompileKernel=*/true, /*Recover=*/true));
|
/*CompileKernel=*/true, /*Recover=*/true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CodeGenOpts.OptimizationLevel == 0)
|
if (CodeGenOpts.OptimizationLevel == 0) {
|
||||||
|
if (CodeGenOpts.SanitizeCoverageType ||
|
||||||
|
CodeGenOpts.SanitizeCoverageIndirectCalls ||
|
||||||
|
CodeGenOpts.SanitizeCoverageTraceCmp) {
|
||||||
|
auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
|
||||||
|
MPM.addPass(ModuleSanitizerCoveragePass(SancovOpts));
|
||||||
|
MPM.addPass(createModuleToFunctionPassAdaptor(
|
||||||
|
SanitizerCoveragePass(SancovOpts)));
|
||||||
|
}
|
||||||
|
|
||||||
addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts);
|
addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: We still use the legacy pass manager to do code generation. We
|
// FIXME: We still use the legacy pass manager to do code generation. We
|
||||||
// create that pass manager here and use it as needed below.
|
// create that pass manager here and use it as needed below.
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Test that SanitizerCoverage works under the new pass manager.
|
||||||
|
// RUN: %clang -target x86_64-linux-gnu -fsanitize=fuzzer %s -fexperimental-new-pass-manager -S -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-O0
|
||||||
|
// RUN: %clang -target x86_64-linux-gnu -fsanitize=fuzzer %s -fexperimental-new-pass-manager -O2 -S -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-O2
|
||||||
|
// RUN: %clang -target x86_64-linux-gnu -fsanitize=fuzzer %s -fexperimental-new-pass-manager -flto -S -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-O0
|
||||||
|
// RUN: %clang -target x86_64-linux-gnu -fsanitize=fuzzer %s -fexperimental-new-pass-manager -flto -O2 -S -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-O2
|
||||||
|
// RUN: %clang -target x86_64-linux-gnu -fsanitize=fuzzer %s -fexperimental-new-pass-manager -flto=thin -S -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-O0
|
||||||
|
// RUN: %clang -target x86_64-linux-gnu -fsanitize=fuzzer %s -fexperimental-new-pass-manager -flto=thin -O2 -S -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-O2,CHECK-O2-THINLTO
|
||||||
|
|
||||||
|
extern void *memcpy(void *, const void *, unsigned long);
|
||||||
|
extern int printf(const char *restrict, ...);
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) {
|
||||||
|
unsigned char buf[4];
|
||||||
|
|
||||||
|
if (size < 8)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (data[0] == 'h' && data[1] == 'i' && data[2] == '!') {
|
||||||
|
memcpy(buf, data, size);
|
||||||
|
printf("test: %.2X\n", buf[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-DAG: declare void @__sanitizer_cov_pcs_init(i64*, i64*)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_pc_indir(i64)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_cmp1(i8 zeroext, i8 zeroext)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_cmp2(i16 zeroext, i16 zeroext)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_cmp4(i32 zeroext, i32 zeroext)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_cmp8(i64, i64)
|
||||||
|
// CHECK-O2-THINLTO-NOT: declare void @__sanitizer_cov_trace_const_cmp1(i8 zeroext, i8 zeroext)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_const_cmp2(i16 zeroext, i16 zeroext)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_const_cmp4(i32 zeroext, i32 zeroext)
|
||||||
|
// CHECK-O2-THINLTO-NOT: declare void @__sanitizer_cov_trace_const_cmp8(i64, i64)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_div4(i32 zeroext)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_div8(i64)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_gep(i64)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_switch(i64, i64*)
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_pc()
|
||||||
|
// CHECK-O0-DAG: declare void @__sanitizer_cov_trace_pc_guard(i32*)
|
|
@ -360,7 +360,9 @@ void initializeSROALegacyPassPass(PassRegistry&);
|
||||||
void initializeSafeStackLegacyPassPass(PassRegistry&);
|
void initializeSafeStackLegacyPassPass(PassRegistry&);
|
||||||
void initializeSafepointIRVerifierPass(PassRegistry&);
|
void initializeSafepointIRVerifierPass(PassRegistry&);
|
||||||
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&);
|
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&);
|
||||||
void initializeSanitizerCoverageModulePass(PassRegistry&);
|
void initializeSanitizerCoverageFunctionCheckLegacyPassPass(PassRegistry &);
|
||||||
|
void initializeSanitizerCoverageLegacyPassPass(PassRegistry &);
|
||||||
|
void initializeModuleSanitizerCoverageLegacyPassPass(PassRegistry &);
|
||||||
void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
|
void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
|
||||||
void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
|
void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
|
||||||
void initializeScalarizerLegacyPassPass(PassRegistry&);
|
void initializeScalarizerLegacyPassPass(PassRegistry&);
|
||||||
|
|
|
@ -181,10 +181,6 @@ struct SanitizerCoverageOptions {
|
||||||
SanitizerCoverageOptions() = default;
|
SanitizerCoverageOptions() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Insert SanitizerCoverage instrumentation.
|
|
||||||
ModulePass *createSanitizerCoverageModulePass(
|
|
||||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions());
|
|
||||||
|
|
||||||
/// Calculate what to divide by to scale counts.
|
/// Calculate what to divide by to scale counts.
|
||||||
///
|
///
|
||||||
/// Given the maximum count, calculate a divisor that will scale all the
|
/// Given the maximum count, calculate a divisor that will scale all the
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
//===--------- Definition of the SanitizerCoverage class --------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file declares the SanitizerCoverage class which is a port of the legacy
|
||||||
|
// SanitizerCoverage pass to use the new PassManager infrastructure.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERCOVERAGE_H
|
||||||
|
#define LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERCOVERAGE_H
|
||||||
|
|
||||||
|
#include "llvm/IR/Function.h"
|
||||||
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PassManager.h"
|
||||||
|
#include "llvm/Transforms/Instrumentation.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// This is the SanitizerCoverage pass used in the new pass manager. The
|
||||||
|
/// pass instruments functions for coverage.
|
||||||
|
class SanitizerCoveragePass : public PassInfoMixin<SanitizerCoveragePass> {
|
||||||
|
public:
|
||||||
|
explicit SanitizerCoveragePass(
|
||||||
|
SanitizerCoverageOptions Options = SanitizerCoverageOptions())
|
||||||
|
: Options(Options) {}
|
||||||
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SanitizerCoverageOptions Options;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This is the ModuleSanitizerCoverage pass used in the new pass manager. This
|
||||||
|
/// adds initialization calls to the module for trace PC guards and 8bit
|
||||||
|
/// counters if they are requested.
|
||||||
|
class ModuleSanitizerCoveragePass
|
||||||
|
: public PassInfoMixin<ModuleSanitizerCoveragePass> {
|
||||||
|
public:
|
||||||
|
explicit ModuleSanitizerCoveragePass(
|
||||||
|
SanitizerCoverageOptions Options = SanitizerCoverageOptions())
|
||||||
|
: Options(Options) {}
|
||||||
|
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SanitizerCoverageOptions Options;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Insert SanitizerCoverage instrumentation.
|
||||||
|
FunctionPass *createSanitizerCoverageLegacyPassPass(
|
||||||
|
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions());
|
||||||
|
ModulePass *createModuleSanitizerCoverageLegacyPassPass(
|
||||||
|
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions());
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
|
@ -101,6 +101,7 @@
|
||||||
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
||||||
#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
|
#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
|
||||||
#include "llvm/Transforms/Instrumentation/PoisonChecking.h"
|
#include "llvm/Transforms/Instrumentation/PoisonChecking.h"
|
||||||
|
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
|
||||||
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
||||||
#include "llvm/Transforms/Scalar/ADCE.h"
|
#include "llvm/Transforms/Scalar/ADCE.h"
|
||||||
#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
|
#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
|
||||||
|
@ -143,8 +144,8 @@
|
||||||
#include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
|
#include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
|
||||||
#include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
|
#include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
|
||||||
#include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
|
#include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
|
||||||
#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
|
|
||||||
#include "llvm/Transforms/Scalar/MergeICmps.h"
|
#include "llvm/Transforms/Scalar/MergeICmps.h"
|
||||||
|
#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
|
||||||
#include "llvm/Transforms/Scalar/NaryReassociate.h"
|
#include "llvm/Transforms/Scalar/NaryReassociate.h"
|
||||||
#include "llvm/Transforms/Scalar/NewGVN.h"
|
#include "llvm/Transforms/Scalar/NewGVN.h"
|
||||||
#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
|
#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
|
||||||
|
|
|
@ -88,6 +88,7 @@ MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass(nullptr, nullptr))
|
||||||
MODULE_PASS("verify", VerifierPass())
|
MODULE_PASS("verify", VerifierPass())
|
||||||
MODULE_PASS("asan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/false, false, true, false))
|
MODULE_PASS("asan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/false, false, true, false))
|
||||||
MODULE_PASS("kasan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/true, false, true, false))
|
MODULE_PASS("kasan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/true, false, true, false))
|
||||||
|
MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass())
|
||||||
MODULE_PASS("poison-checking", PoisonCheckingPass())
|
MODULE_PASS("poison-checking", PoisonCheckingPass())
|
||||||
#undef MODULE_PASS
|
#undef MODULE_PASS
|
||||||
|
|
||||||
|
@ -245,6 +246,7 @@ FUNCTION_PASS("kasan", AddressSanitizerPass(true, false, false))
|
||||||
FUNCTION_PASS("msan", MemorySanitizerPass({}))
|
FUNCTION_PASS("msan", MemorySanitizerPass({}))
|
||||||
FUNCTION_PASS("kmsan", MemorySanitizerPass({0, false, /*Kernel=*/true}))
|
FUNCTION_PASS("kmsan", MemorySanitizerPass({0, false, /*Kernel=*/true}))
|
||||||
FUNCTION_PASS("tsan", ThreadSanitizerPass())
|
FUNCTION_PASS("tsan", ThreadSanitizerPass())
|
||||||
|
FUNCTION_PASS("sancov-func", SanitizerCoveragePass())
|
||||||
#undef FUNCTION_PASS
|
#undef FUNCTION_PASS
|
||||||
|
|
||||||
#ifndef FUNCTION_PASS_WITH_PARAMS
|
#ifndef FUNCTION_PASS_WITH_PARAMS
|
||||||
|
|
|
@ -116,7 +116,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) {
|
||||||
initializeMemorySanitizerLegacyPassPass(Registry);
|
initializeMemorySanitizerLegacyPassPass(Registry);
|
||||||
initializeHWAddressSanitizerLegacyPassPass(Registry);
|
initializeHWAddressSanitizerLegacyPassPass(Registry);
|
||||||
initializeThreadSanitizerLegacyPassPass(Registry);
|
initializeThreadSanitizerLegacyPassPass(Registry);
|
||||||
initializeSanitizerCoverageModulePass(Registry);
|
initializeSanitizerCoverageLegacyPassPass(Registry);
|
||||||
initializeDataFlowSanitizerPass(Registry);
|
initializeDataFlowSanitizerPass(Registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/Analysis/EHPersonalities.h"
|
#include "llvm/Analysis/EHPersonalities.h"
|
||||||
|
@ -176,24 +177,168 @@ SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
|
||||||
return Options;
|
return Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SanitizerCoverageModule : public ModulePass {
|
bool canInstrumentWithSancov(const Function &F) {
|
||||||
public:
|
if (F.empty())
|
||||||
SanitizerCoverageModule(
|
return false;
|
||||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
|
if (F.getName().find(".module_ctor") != std::string::npos)
|
||||||
: ModulePass(ID), Options(OverrideFromCL(Options)) {
|
return false; // Should not instrument sanitizer init functions.
|
||||||
initializeSanitizerCoverageModulePass(*PassRegistry::getPassRegistry());
|
if (F.getName().startswith("__sanitizer_"))
|
||||||
}
|
return false; // Don't instrument __sanitizer_* callbacks.
|
||||||
bool runOnModule(Module &M) override;
|
// Don't touch available_externally functions, their actual body is elewhere.
|
||||||
bool runOnFunction(Function &F);
|
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
|
||||||
static char ID; // Pass identification, replacement for typeid
|
return false;
|
||||||
StringRef getPassName() const override { return "SanitizerCoverageModule"; }
|
// Don't instrument MSVC CRT configuration helpers. They may run before normal
|
||||||
|
// initialization.
|
||||||
|
if (F.getName() == "__local_stdio_printf_options" ||
|
||||||
|
F.getName() == "__local_stdio_scanf_options")
|
||||||
|
return false;
|
||||||
|
if (isa<UnreachableInst>(F.getEntryBlock().getTerminator()))
|
||||||
|
return false;
|
||||||
|
// Don't instrument functions using SEH for now. Splitting basic blocks like
|
||||||
|
// we do for coverage breaks WinEHPrepare.
|
||||||
|
// FIXME: Remove this when SEH no longer uses landingpad pattern matching.
|
||||||
|
if (F.hasPersonalityFn() &&
|
||||||
|
isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
std::string getSectionStartImpl(const Triple &TargetTriple,
|
||||||
AU.addRequired<DominatorTreeWrapperPass>();
|
const std::string &Section) {
|
||||||
AU.addRequired<PostDominatorTreeWrapperPass>();
|
if (TargetTriple.isOSBinFormatMachO())
|
||||||
|
return "\1section$start$__DATA$__" + Section;
|
||||||
|
return "__start___" + Section;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getSectionEndImpl(const Triple &TargetTriple,
|
||||||
|
const std::string &Section) {
|
||||||
|
if (TargetTriple.isOSBinFormatMachO())
|
||||||
|
return "\1section$end$__DATA$__" + Section;
|
||||||
|
return "__stop___" + Section;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is a class for instrumenting the module to add calls to initializing
|
||||||
|
/// the trace PC guards and 8bit counter globals. This should only be done
|
||||||
|
/// though if there is at least one function that can be instrumented with
|
||||||
|
/// Sancov.
|
||||||
|
class ModuleSanitizerCoverage {
|
||||||
|
public:
|
||||||
|
ModuleSanitizerCoverage(const SanitizerCoverageOptions &Options)
|
||||||
|
: Options(OverrideFromCL(Options)) {}
|
||||||
|
|
||||||
|
bool instrumentModule(Module &M) {
|
||||||
|
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Function *Ctor = nullptr;
|
||||||
|
LLVMContext *C = &(M.getContext());
|
||||||
|
const DataLayout *DL = &M.getDataLayout();
|
||||||
|
TargetTriple = Triple(M.getTargetTriple());
|
||||||
|
IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
|
||||||
|
Type *IntptrPtrTy = PointerType::getUnqual(IntptrTy);
|
||||||
|
IRBuilder<> IRB(*C);
|
||||||
|
Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
|
||||||
|
Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
|
||||||
|
Int8Ty = IRB.getInt8Ty();
|
||||||
|
|
||||||
|
// Check that the __sancov_lowest_stack marker does not already exist.
|
||||||
|
Constant *SanCovLowestStackConstant =
|
||||||
|
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
|
||||||
|
GlobalVariable *SanCovLowestStack =
|
||||||
|
dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
|
||||||
|
if (!SanCovLowestStack) {
|
||||||
|
C->emitError(StringRef("'") + SanCovLowestStackName +
|
||||||
|
"' should not be declared by the user");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want to emit guard init calls if the module contains a function that
|
||||||
|
// we can instrument with SanitizerCoverage. We ignore any functions that
|
||||||
|
// were inserted by SanitizerCoverage and get the result from the analysis
|
||||||
|
// that checks for a valid function that the analysis may have run over.
|
||||||
|
if (!llvm::any_of(
|
||||||
|
M, [](const Function &F) { return canInstrumentWithSancov(F); }))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Emit the init calls.
|
||||||
|
if (Options.TracePCGuard)
|
||||||
|
Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName,
|
||||||
|
SanCovTracePCGuardInitName, Int32PtrTy,
|
||||||
|
SanCovGuardsSectionName);
|
||||||
|
if (Options.Inline8bitCounters)
|
||||||
|
Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName,
|
||||||
|
SanCov8bitCountersInitName, Int8PtrTy,
|
||||||
|
SanCovCountersSectionName);
|
||||||
|
if (Ctor && Options.PCTable) {
|
||||||
|
auto SecStartEnd =
|
||||||
|
CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy);
|
||||||
|
FunctionCallee InitFunction = declareSanitizerInitFunction(
|
||||||
|
M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
|
||||||
|
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
|
||||||
|
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
|
||||||
|
}
|
||||||
|
return Ctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Function *CreateInitCallsForSections(Module &M, const char *CtorName,
|
||||||
|
const char *InitFunctionName, Type *Ty,
|
||||||
|
const char *Section);
|
||||||
|
std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section,
|
||||||
|
Type *Ty);
|
||||||
|
std::string getSectionStart(const std::string &Section) const {
|
||||||
|
return getSectionStartImpl(TargetTriple, Section);
|
||||||
|
}
|
||||||
|
std::string getSectionEnd(const std::string &Section) const {
|
||||||
|
return getSectionEndImpl(TargetTriple, Section);
|
||||||
|
}
|
||||||
|
|
||||||
|
SanitizerCoverageOptions Options;
|
||||||
|
Triple TargetTriple;
|
||||||
|
Type *IntptrTy, *Int8PtrTy, *Int8Ty;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModuleSanitizerCoverageLegacyPass : public ModulePass {
|
||||||
|
public:
|
||||||
|
static char ID;
|
||||||
|
|
||||||
|
ModuleSanitizerCoverageLegacyPass(
|
||||||
|
SanitizerCoverageOptions Options = SanitizerCoverageOptions())
|
||||||
|
: ModulePass(ID), Options(Options) {
|
||||||
|
initializeModuleSanitizerCoverageLegacyPassPass(
|
||||||
|
*PassRegistry::getPassRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runOnModule(Module &M) override {
|
||||||
|
ModuleSanitizerCoverage ModuleSancov(Options);
|
||||||
|
return ModuleSancov.instrumentModule(M);
|
||||||
|
};
|
||||||
|
|
||||||
|
StringRef getPassName() const override {
|
||||||
|
return "ModuleSanitizerCoverageLegacyPass";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SanitizerCoverageOptions Options;
|
||||||
|
};
|
||||||
|
|
||||||
|
char ModuleSanitizerCoverageLegacyPass::ID = 0;
|
||||||
|
|
||||||
|
class SanitizerCoverage {
|
||||||
|
public:
|
||||||
|
SanitizerCoverage(Function &F, const SanitizerCoverageOptions &Options)
|
||||||
|
: CurModule(F.getParent()), Options(OverrideFromCL(Options)) {
|
||||||
|
initializeModule(*F.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
~SanitizerCoverage() { finalizeModule(*CurModule); }
|
||||||
|
|
||||||
|
bool instrumentFunction(Function &F, const DominatorTree *DT,
|
||||||
|
const PostDominatorTree *PDT);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initializeModule(Module &M);
|
||||||
|
void finalizeModule(Module &M);
|
||||||
void InjectCoverageForIndirectCalls(Function &F,
|
void InjectCoverageForIndirectCalls(Function &F,
|
||||||
ArrayRef<Instruction *> IndirCalls);
|
ArrayRef<Instruction *> IndirCalls);
|
||||||
void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
|
void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
|
||||||
|
@ -212,11 +357,6 @@ private:
|
||||||
void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks);
|
||||||
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
|
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
|
||||||
bool IsLeafFunc = true);
|
bool IsLeafFunc = true);
|
||||||
Function *CreateInitCallsForSections(Module &M, const char *CtorName,
|
|
||||||
const char *InitFunctionName, Type *Ty,
|
|
||||||
const char *Section);
|
|
||||||
std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section,
|
|
||||||
Type *Ty);
|
|
||||||
|
|
||||||
void SetNoSanitizeMetadata(Instruction *I) {
|
void SetNoSanitizeMetadata(Instruction *I) {
|
||||||
I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
|
I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
|
||||||
|
@ -252,10 +392,63 @@ private:
|
||||||
SanitizerCoverageOptions Options;
|
SanitizerCoverageOptions Options;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SanitizerCoverageLegacyPass : public FunctionPass {
|
||||||
|
public:
|
||||||
|
static char ID; // Pass identification, replacement for typeid
|
||||||
|
|
||||||
|
SanitizerCoverageLegacyPass(
|
||||||
|
SanitizerCoverageOptions Options = SanitizerCoverageOptions())
|
||||||
|
: FunctionPass(ID), Options(Options) {
|
||||||
|
initializeSanitizerCoverageLegacyPassPass(*PassRegistry::getPassRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runOnFunction(Function &F) override {
|
||||||
|
const DominatorTree *DT =
|
||||||
|
&getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||||
|
const PostDominatorTree *PDT =
|
||||||
|
&getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
|
||||||
|
SanitizerCoverage Sancov(F, Options);
|
||||||
|
return Sancov.instrumentFunction(F, DT, PDT);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef getPassName() const override {
|
||||||
|
return "SanitizerCoverageLegacyPass";
|
||||||
|
}
|
||||||
|
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||||
|
// Make the module sancov pass required by this pass so that it runs when
|
||||||
|
// -sancov is passed.
|
||||||
|
AU.addRequired<ModuleSanitizerCoverageLegacyPass>();
|
||||||
|
AU.addRequired<DominatorTreeWrapperPass>();
|
||||||
|
AU.addRequired<PostDominatorTreeWrapperPass>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SanitizerCoverageOptions Options;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
PreservedAnalyses SanitizerCoveragePass::run(Function &F,
|
||||||
|
FunctionAnalysisManager &AM) {
|
||||||
|
const DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
|
||||||
|
const PostDominatorTree *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F);
|
||||||
|
SanitizerCoverage Sancov(F, Options);
|
||||||
|
if (Sancov.instrumentFunction(F, DT, PDT))
|
||||||
|
return PreservedAnalyses::none();
|
||||||
|
return PreservedAnalyses::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreservedAnalyses ModuleSanitizerCoveragePass::run(Module &M,
|
||||||
|
ModuleAnalysisManager &AM) {
|
||||||
|
ModuleSanitizerCoverage ModuleSancov(Options);
|
||||||
|
if (ModuleSancov.instrumentModule(M))
|
||||||
|
return PreservedAnalyses::none();
|
||||||
|
return PreservedAnalyses::all();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<Value *, Value *>
|
std::pair<Value *, Value *>
|
||||||
SanitizerCoverageModule::CreateSecStartEnd(Module &M, const char *Section,
|
ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section,
|
||||||
Type *Ty) {
|
Type *Ty) {
|
||||||
GlobalVariable *SecStart =
|
GlobalVariable *SecStart =
|
||||||
new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr,
|
new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr,
|
||||||
|
@ -265,6 +458,7 @@ SanitizerCoverageModule::CreateSecStartEnd(Module &M, const char *Section,
|
||||||
new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
|
new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
|
||||||
nullptr, getSectionEnd(Section));
|
nullptr, getSectionEnd(Section));
|
||||||
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
|
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
|
||||||
|
|
||||||
IRBuilder<> IRB(M.getContext());
|
IRBuilder<> IRB(M.getContext());
|
||||||
Value *SecEndPtr = IRB.CreatePointerCast(SecEnd, Ty);
|
Value *SecEndPtr = IRB.CreatePointerCast(SecEnd, Ty);
|
||||||
if (!TargetTriple.isOSBinFormatCOFF())
|
if (!TargetTriple.isOSBinFormatCOFF())
|
||||||
|
@ -278,7 +472,7 @@ SanitizerCoverageModule::CreateSecStartEnd(Module &M, const char *Section,
|
||||||
return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEndPtr);
|
return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEndPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Function *SanitizerCoverageModule::CreateInitCallsForSections(
|
Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
|
||||||
Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
|
Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
|
||||||
const char *Section) {
|
const char *Section) {
|
||||||
auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
|
auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
|
||||||
|
@ -310,12 +504,11 @@ Function *SanitizerCoverageModule::CreateInitCallsForSections(
|
||||||
return CtorFunc;
|
return CtorFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SanitizerCoverageModule::runOnModule(Module &M) {
|
void SanitizerCoverage::initializeModule(Module &M) {
|
||||||
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
|
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
|
||||||
return false;
|
return;
|
||||||
C = &(M.getContext());
|
C = &(M.getContext());
|
||||||
DL = &M.getDataLayout();
|
DL = &M.getDataLayout();
|
||||||
CurModule = &M;
|
|
||||||
CurModuleUniqueId = getUniqueModuleId(CurModule);
|
CurModuleUniqueId = getUniqueModuleId(CurModule);
|
||||||
TargetTriple = Triple(M.getTargetTriple());
|
TargetTriple = Triple(M.getTargetTriple());
|
||||||
FunctionGuardArray = nullptr;
|
FunctionGuardArray = nullptr;
|
||||||
|
@ -383,11 +576,6 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
||||||
Constant *SanCovLowestStackConstant =
|
Constant *SanCovLowestStackConstant =
|
||||||
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
|
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
|
||||||
SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
|
SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
|
||||||
if (!SanCovLowestStack) {
|
|
||||||
C->emitError(StringRef("'") + SanCovLowestStackName +
|
|
||||||
"' should not be declared by the user");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
SanCovLowestStack->setThreadLocalMode(
|
SanCovLowestStack->setThreadLocalMode(
|
||||||
GlobalValue::ThreadLocalMode::InitialExecTLSModel);
|
GlobalValue::ThreadLocalMode::InitialExecTLSModel);
|
||||||
if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
|
if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
|
||||||
|
@ -401,33 +589,14 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
||||||
SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
|
SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
|
||||||
SanCovTracePCGuard =
|
SanCovTracePCGuard =
|
||||||
M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
|
M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &F : M)
|
void SanitizerCoverage::finalizeModule(Module &M) {
|
||||||
runOnFunction(F);
|
|
||||||
|
|
||||||
Function *Ctor = nullptr;
|
|
||||||
|
|
||||||
if (FunctionGuardArray)
|
|
||||||
Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName,
|
|
||||||
SanCovTracePCGuardInitName, Int32PtrTy,
|
|
||||||
SanCovGuardsSectionName);
|
|
||||||
if (Function8bitCounterArray)
|
|
||||||
Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName,
|
|
||||||
SanCov8bitCountersInitName, Int8PtrTy,
|
|
||||||
SanCovCountersSectionName);
|
|
||||||
if (Ctor && Options.PCTable) {
|
|
||||||
auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy);
|
|
||||||
FunctionCallee InitFunction = declareSanitizerInitFunction(
|
|
||||||
M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
|
|
||||||
IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
|
|
||||||
IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
|
|
||||||
}
|
|
||||||
// We don't reference these arrays directly in any of our runtime functions,
|
// We don't reference these arrays directly in any of our runtime functions,
|
||||||
// so we need to prevent them from being dead stripped.
|
// so we need to prevent them from being dead stripped.
|
||||||
if (TargetTriple.isOSBinFormatMachO())
|
if (TargetTriple.isOSBinFormatMachO())
|
||||||
appendToUsed(M, GlobalsToAppendToUsed);
|
appendToUsed(M, GlobalsToAppendToUsed);
|
||||||
appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
|
appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// True if block has successors and it dominates all of them.
|
// True if block has successors and it dominates all of them.
|
||||||
|
@ -518,28 +687,11 @@ static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SanitizerCoverageModule::runOnFunction(Function &F) {
|
bool SanitizerCoverage::instrumentFunction(Function &F, const DominatorTree *DT,
|
||||||
if (F.empty())
|
const PostDominatorTree *PDT) {
|
||||||
|
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None)
|
||||||
return false;
|
return false;
|
||||||
if (F.getName().find(".module_ctor") != std::string::npos)
|
if (!canInstrumentWithSancov(F))
|
||||||
return false; // Should not instrument sanitizer init functions.
|
|
||||||
if (F.getName().startswith("__sanitizer_"))
|
|
||||||
return false; // Don't instrument __sanitizer_* callbacks.
|
|
||||||
// Don't touch available_externally functions, their actual body is elewhere.
|
|
||||||
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
|
|
||||||
return false;
|
|
||||||
// Don't instrument MSVC CRT configuration helpers. They may run before normal
|
|
||||||
// initialization.
|
|
||||||
if (F.getName() == "__local_stdio_printf_options" ||
|
|
||||||
F.getName() == "__local_stdio_scanf_options")
|
|
||||||
return false;
|
|
||||||
if (isa<UnreachableInst>(F.getEntryBlock().getTerminator()))
|
|
||||||
return false;
|
|
||||||
// Don't instrument functions using SEH for now. Splitting basic blocks like
|
|
||||||
// we do for coverage breaks WinEHPrepare.
|
|
||||||
// FIXME: Remove this when SEH no longer uses landingpad pattern matching.
|
|
||||||
if (F.hasPersonalityFn() &&
|
|
||||||
isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
|
||||||
return false;
|
return false;
|
||||||
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
|
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
|
||||||
SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
|
SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
|
||||||
|
@ -550,10 +702,6 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
|
||||||
SmallVector<BinaryOperator *, 8> DivTraceTargets;
|
SmallVector<BinaryOperator *, 8> DivTraceTargets;
|
||||||
SmallVector<GetElementPtrInst *, 8> GepTraceTargets;
|
SmallVector<GetElementPtrInst *, 8> GepTraceTargets;
|
||||||
|
|
||||||
const DominatorTree *DT =
|
|
||||||
&getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
|
|
||||||
const PostDominatorTree *PDT =
|
|
||||||
&getAnalysis<PostDominatorTreeWrapperPass>(F).getPostDomTree();
|
|
||||||
bool IsLeafFunc = true;
|
bool IsLeafFunc = true;
|
||||||
|
|
||||||
for (auto &BB : F) {
|
for (auto &BB : F) {
|
||||||
|
@ -596,7 +744,7 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalVariable *SanitizerCoverageModule::CreateFunctionLocalArrayInSection(
|
GlobalVariable *SanitizerCoverage::CreateFunctionLocalArrayInSection(
|
||||||
size_t NumElements, Function &F, Type *Ty, const char *Section) {
|
size_t NumElements, Function &F, Type *Ty, const char *Section) {
|
||||||
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
|
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
|
||||||
auto Array = new GlobalVariable(
|
auto Array = new GlobalVariable(
|
||||||
|
@ -619,7 +767,7 @@ GlobalVariable *SanitizerCoverageModule::CreateFunctionLocalArrayInSection(
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalVariable *
|
GlobalVariable *
|
||||||
SanitizerCoverageModule::CreatePCArray(Function &F,
|
SanitizerCoverage::CreatePCArray(Function &F,
|
||||||
ArrayRef<BasicBlock *> AllBlocks) {
|
ArrayRef<BasicBlock *> AllBlocks) {
|
||||||
size_t N = AllBlocks.size();
|
size_t N = AllBlocks.size();
|
||||||
assert(N);
|
assert(N);
|
||||||
|
@ -646,7 +794,7 @@ SanitizerCoverageModule::CreatePCArray(Function &F,
|
||||||
return PCArray;
|
return PCArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SanitizerCoverageModule::CreateFunctionLocalArrays(
|
void SanitizerCoverage::CreateFunctionLocalArrays(
|
||||||
Function &F, ArrayRef<BasicBlock *> AllBlocks) {
|
Function &F, ArrayRef<BasicBlock *> AllBlocks) {
|
||||||
if (Options.TracePCGuard)
|
if (Options.TracePCGuard)
|
||||||
FunctionGuardArray = CreateFunctionLocalArrayInSection(
|
FunctionGuardArray = CreateFunctionLocalArrayInSection(
|
||||||
|
@ -660,7 +808,7 @@ void SanitizerCoverageModule::CreateFunctionLocalArrays(
|
||||||
FunctionPCsArray = CreatePCArray(F, AllBlocks);
|
FunctionPCsArray = CreatePCArray(F, AllBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SanitizerCoverageModule::InjectCoverage(Function &F,
|
bool SanitizerCoverage::InjectCoverage(Function &F,
|
||||||
ArrayRef<BasicBlock *> AllBlocks,
|
ArrayRef<BasicBlock *> AllBlocks,
|
||||||
bool IsLeafFunc) {
|
bool IsLeafFunc) {
|
||||||
if (AllBlocks.empty()) return false;
|
if (AllBlocks.empty()) return false;
|
||||||
|
@ -677,7 +825,7 @@ bool SanitizerCoverageModule::InjectCoverage(Function &F,
|
||||||
// The cache is used to speed up recording the caller-callee pairs.
|
// The cache is used to speed up recording the caller-callee pairs.
|
||||||
// The address of the caller is passed implicitly via caller PC.
|
// The address of the caller is passed implicitly via caller PC.
|
||||||
// CacheSize is encoded in the name of the run-time function.
|
// CacheSize is encoded in the name of the run-time function.
|
||||||
void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
|
void SanitizerCoverage::InjectCoverageForIndirectCalls(
|
||||||
Function &F, ArrayRef<Instruction *> IndirCalls) {
|
Function &F, ArrayRef<Instruction *> IndirCalls) {
|
||||||
if (IndirCalls.empty())
|
if (IndirCalls.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -696,7 +844,7 @@ void SanitizerCoverageModule::InjectCoverageForIndirectCalls(
|
||||||
// __sanitizer_cov_trace_switch(CondValue,
|
// __sanitizer_cov_trace_switch(CondValue,
|
||||||
// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
|
// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
|
||||||
|
|
||||||
void SanitizerCoverageModule::InjectTraceForSwitch(
|
void SanitizerCoverage::InjectTraceForSwitch(
|
||||||
Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
|
Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
|
||||||
for (auto I : SwitchTraceTargets) {
|
for (auto I : SwitchTraceTargets) {
|
||||||
if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
|
if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
|
||||||
|
@ -735,7 +883,7 @@ void SanitizerCoverageModule::InjectTraceForSwitch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SanitizerCoverageModule::InjectTraceForDiv(
|
void SanitizerCoverage::InjectTraceForDiv(
|
||||||
Function &, ArrayRef<BinaryOperator *> DivTraceTargets) {
|
Function &, ArrayRef<BinaryOperator *> DivTraceTargets) {
|
||||||
for (auto BO : DivTraceTargets) {
|
for (auto BO : DivTraceTargets) {
|
||||||
IRBuilder<> IRB(BO);
|
IRBuilder<> IRB(BO);
|
||||||
|
@ -753,7 +901,7 @@ void SanitizerCoverageModule::InjectTraceForDiv(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SanitizerCoverageModule::InjectTraceForGep(
|
void SanitizerCoverage::InjectTraceForGep(
|
||||||
Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) {
|
Function &, ArrayRef<GetElementPtrInst *> GepTraceTargets) {
|
||||||
for (auto GEP : GepTraceTargets) {
|
for (auto GEP : GepTraceTargets) {
|
||||||
IRBuilder<> IRB(GEP);
|
IRBuilder<> IRB(GEP);
|
||||||
|
@ -764,7 +912,7 @@ void SanitizerCoverageModule::InjectTraceForGep(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SanitizerCoverageModule::InjectTraceForCmp(
|
void SanitizerCoverage::InjectTraceForCmp(
|
||||||
Function &, ArrayRef<Instruction *> CmpTraceTargets) {
|
Function &, ArrayRef<Instruction *> CmpTraceTargets) {
|
||||||
for (auto I : CmpTraceTargets) {
|
for (auto I : CmpTraceTargets) {
|
||||||
if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
|
if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
|
||||||
|
@ -799,9 +947,8 @@ void SanitizerCoverageModule::InjectTraceForCmp(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
void SanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
||||||
size_t Idx,
|
size_t Idx, bool IsLeafFunc) {
|
||||||
bool IsLeafFunc) {
|
|
||||||
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
||||||
bool IsEntryBB = &BB == &F.getEntryBlock();
|
bool IsEntryBB = &BB == &F.getEntryBlock();
|
||||||
DebugLoc EntryLoc;
|
DebugLoc EntryLoc;
|
||||||
|
@ -860,7 +1007,7 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
SanitizerCoverageModule::getSectionName(const std::string &Section) const {
|
SanitizerCoverage::getSectionName(const std::string &Section) const {
|
||||||
if (TargetTriple.isOSBinFormatCOFF()) {
|
if (TargetTriple.isOSBinFormatCOFF()) {
|
||||||
if (Section == SanCovCountersSectionName)
|
if (Section == SanCovCountersSectionName)
|
||||||
return ".SCOV$CM";
|
return ".SCOV$CM";
|
||||||
|
@ -874,32 +1021,33 @@ SanitizerCoverageModule::getSectionName(const std::string &Section) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
SanitizerCoverageModule::getSectionStart(const std::string &Section) const {
|
SanitizerCoverage::getSectionStart(const std::string &Section) const {
|
||||||
if (TargetTriple.isOSBinFormatMachO())
|
return getSectionStartImpl(TargetTriple, Section);
|
||||||
return "\1section$start$__DATA$__" + Section;
|
|
||||||
return "__start___" + Section;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string SanitizerCoverage::getSectionEnd(const std::string &Section) const {
|
||||||
SanitizerCoverageModule::getSectionEnd(const std::string &Section) const {
|
return getSectionEndImpl(TargetTriple, Section);
|
||||||
if (TargetTriple.isOSBinFormatMachO())
|
|
||||||
return "\1section$end$__DATA$__" + Section;
|
|
||||||
return "__stop___" + Section;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INITIALIZE_PASS(ModuleSanitizerCoverageLegacyPass, "module-sancov",
|
||||||
char SanitizerCoverageModule::ID = 0;
|
"Pass for inserting sancov top-level initialization calls",
|
||||||
INITIALIZE_PASS_BEGIN(SanitizerCoverageModule, "sancov",
|
|
||||||
"SanitizerCoverage: TODO."
|
|
||||||
"ModulePass",
|
|
||||||
false, false)
|
false, false)
|
||||||
|
|
||||||
|
char SanitizerCoverageLegacyPass::ID = 0;
|
||||||
|
INITIALIZE_PASS_BEGIN(SanitizerCoverageLegacyPass, "sancov",
|
||||||
|
"Pass for instrumenting coverage on functions", false,
|
||||||
|
false)
|
||||||
|
INITIALIZE_PASS_DEPENDENCY(ModuleSanitizerCoverageLegacyPass)
|
||||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||||
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
|
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
|
||||||
INITIALIZE_PASS_END(SanitizerCoverageModule, "sancov",
|
INITIALIZE_PASS_END(SanitizerCoverageLegacyPass, "sancov",
|
||||||
"SanitizerCoverage: TODO."
|
"Pass for instrumenting coverage on functions", false,
|
||||||
"ModulePass",
|
false)
|
||||||
false, false)
|
FunctionPass *llvm::createSanitizerCoverageLegacyPassPass(
|
||||||
ModulePass *llvm::createSanitizerCoverageModulePass(
|
|
||||||
const SanitizerCoverageOptions &Options) {
|
const SanitizerCoverageOptions &Options) {
|
||||||
return new SanitizerCoverageModule(Options);
|
return new SanitizerCoverageLegacyPass(Options);
|
||||||
|
}
|
||||||
|
ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
|
||||||
|
const SanitizerCoverageOptions &Options) {
|
||||||
|
return new ModuleSanitizerCoverageLegacyPass(Options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Checks that a function with no-return in the entry block is not instrumented.
|
; Checks that a function with no-return in the entry block is not instrumented.
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
; CHECK-NOT: call void @__sanitizer_cov_trace_pc_guard
|
; CHECK-NOT: call void @__sanitizer_cov_trace_pc_guard
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
; Test -sanitizer-coverage-trace-compares=1 and how it prunes backedge compares.
|
; Test -sanitizer-coverage-trace-compares=1 and how it prunes backedge compares.
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=PRUNE
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=PRUNE
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -sanitizer-coverage-prune-blocks=0 -S | FileCheck %s --check-prefix=NOPRUNE
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -sanitizer-coverage-prune-blocks=0 -S | FileCheck %s --check-prefix=NOPRUNE
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=PRUNE
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -sanitizer-coverage-prune-blocks=0 -S | FileCheck %s --check-prefix=NOPRUNE
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s
|
||||||
|
|
||||||
define i32 @blah(i32) #0 {
|
define i32 @blah(i32) #0 {
|
||||||
%2 = icmp sgt i32 %0, 1
|
%2 = icmp sgt i32 %0, 1
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-compares=1 API declarations on a non-x86_64 arch
|
; Test -sanitizer-coverage-trace-compares=1 API declarations on a non-x86_64 arch
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
|
||||||
target triple = "i386-unknown-linux-gnu"
|
target triple = "i386-unknown-linux-gnu"
|
||||||
define i32 @foo() #0 {
|
define i32 @foo() #0 {
|
||||||
|
@ -7,16 +8,16 @@ entry:
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc_indir(i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc_indir(i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp1(i8, i8)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp1(i8, i8)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp2(i16, i16)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp2(i16, i16)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp4(i32, i32)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp4(i32, i32)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp8(i64, i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp8(i64, i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_div4(i32)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_div4(i32)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_div8(i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_div8(i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_gep(i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_gep(i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_switch(i64, i64*)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_switch(i64, i64*)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc()
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc()
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc_guard(i32*)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc_guard(i32*)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc_guard_init(i32*, i32*)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc_guard_init(i32*, i32*)
|
||||||
; CHECK-NOT: declare
|
; CHECK-NOT: declare
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-compares=1 API declarations on x86_64
|
; Test -sanitizer-coverage-trace-compares=1 API declarations on x86_64
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
define i32 @foo() #0 {
|
define i32 @foo() #0 {
|
||||||
|
@ -7,16 +8,16 @@ entry:
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc_indir(i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc_indir(i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp1(i8 zeroext, i8 zeroext)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp1(i8 zeroext, i8 zeroext)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp2(i16 zeroext, i16 zeroext)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp2(i16 zeroext, i16 zeroext)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp4(i32 zeroext, i32 zeroext)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp4(i32 zeroext, i32 zeroext)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_cmp8(i64, i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_cmp8(i64, i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_div4(i32 zeroext)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_div4(i32 zeroext)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_div8(i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_div8(i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_gep(i64)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_gep(i64)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_switch(i64, i64*)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_switch(i64, i64*)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc()
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc()
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc_guard(i32*)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc_guard(i32*)
|
||||||
; CHECK: declare void @__sanitizer_cov_trace_pc_guard_init(i32*, i32*)
|
; CHECK-DAG: declare void @__sanitizer_cov_trace_pc_guard_init(i32*, i32*)
|
||||||
; CHECK-NOT: declare
|
; CHECK-NOT: declare
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-compares=1
|
; Test -sanitizer-coverage-trace-compares=1
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
|
||||||
; Make sure we use the right comdat groups for COFF to avoid relocations
|
; Make sure we use the right comdat groups for COFF to avoid relocations
|
||||||
; against discarded sections. Internal linkage functions are also different from
|
; against discarded sections. Internal linkage functions are also different from
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Checks that the PC and 8-bit Counter Arrays are placed in their own sections in COFF binaries.
|
; Checks that the PC and 8-bit Counter Arrays are placed in their own sections in COFF binaries.
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-pc-windows-msvc19.14.26433"
|
target triple = "x86_64-pc-windows-msvc19.14.26433"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Checks that sancov.module_ctor is marked used.
|
; Checks that sancov.module_ctor is marked used.
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-pc-windows-msvc19.14.26433"
|
target triple = "x86_64-pc-windows-msvc19.14.26433"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-compares=1
|
; Test -sanitizer-coverage-trace-compares=1
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
; Test that coverage instrumentation does not lose debug location.
|
; Test that coverage instrumentation does not lose debug location.
|
||||||
|
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -S | FileCheck %s
|
||||||
|
|
||||||
; C++ source:
|
; C++ source:
|
||||||
; 1: struct A {
|
; 1: struct A {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK_TRACE_PC
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK_TRACE_PC
|
||||||
|
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=CHECKPRUNE
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=CHECKPRUNE
|
||||||
|
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK_TRACE_PC
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=CHECKPRUNE
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
define void @foo(i32* %a) sanitize_address {
|
define void @foo(i32* %a) sanitize_address {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
; Test that coverage instrumentation does not lose debug location.
|
; Test that coverage instrumentation does not lose debug location.
|
||||||
|
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=2 -S | FileCheck %s
|
||||||
|
|
||||||
; C++ source:
|
; C++ source:
|
||||||
; 1: void foo(int *a) {
|
; 1: void foo(int *a) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-divs=1
|
; Test -sanitizer-coverage-trace-divs=1
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-divs=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-divs=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-divs=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-geps=1
|
; Test -sanitizer-coverage-trace-geps=1
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-geps=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-geps=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-geps=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-inline-8bit-counters=1
|
; Test -sanitizer-coverage-inline-8bit-counters=1
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
; Test that interposable symbols do not get put in comdats.
|
; Test that interposable symbols do not get put in comdats.
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -mtriple x86_64-linux-gnu -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -mtriple x86_64-linux-gnu -S | FileCheck %s
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -mtriple x86_64-windows-msvc -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -mtriple x86_64-windows-msvc -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -mtriple x86_64-linux-gnu -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -mtriple x86_64-windows-msvc -S | FileCheck %s
|
||||||
|
|
||||||
define void @Vanilla() {
|
define void @Vanilla() {
|
||||||
entry:
|
entry:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
; Tests that we don't insert __sanitizer_cov_trace_pc_guard_init or some such
|
; Tests that we don't insert __sanitizer_cov_trace_pc_guard_init or some such
|
||||||
; when there is no instrumentation.
|
; when there is no instrumentation.
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
; Test -sanitizer-coverage-pc-table=1
|
; Test -sanitizer-coverage-pc-table=1
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-inline-8bit-counters -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-inline-8bit-counters -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-inline-8bit-counters -sanitizer-coverage-pc-table=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=0 -S | FileCheck %s --check-prefix=CHECK_NO_PRUNE
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=0 -S | FileCheck %s --check-prefix=CHECK_NO_PRUNE
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc -sanitizer-coverage-prune-blocks=0 -S | FileCheck %s --check-prefix=CHECK_NO_PRUNE
|
||||||
|
|
||||||
define i32 @foo(i32) #0 {
|
define i32 @foo(i32) #0 {
|
||||||
%2 = icmp sgt i32 %0, 0
|
%2 = icmp sgt i32 %0, 0
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=0 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=0 -S | FileCheck %s
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=0 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=2 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||||
target triple = "i686-pc-windows-msvc18.0.0"
|
target triple = "i686-pc-windows-msvc18.0.0"
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
; user declares `__sancov_lowest_stack` with an unexpected type.
|
; user declares `__sancov_lowest_stack` with an unexpected type.
|
||||||
; RUN: not opt < %s -sancov -sanitizer-coverage-level=1 \
|
; RUN: not opt < %s -sancov -sanitizer-coverage-level=1 \
|
||||||
; RUN: -sanitizer-coverage-stack-depth -S 2>&1 | FileCheck %s
|
; RUN: -sanitizer-coverage-stack-depth -S 2>&1 | FileCheck %s
|
||||||
|
; RUN: not opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 \
|
||||||
|
; RUN: -sanitizer-coverage-stack-depth -S 2>&1 | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 \
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 \
|
||||||
; RUN: -sanitizer-coverage-stack-depth -sanitizer-coverage-trace-pc-guard \
|
; RUN: -sanitizer-coverage-stack-depth -sanitizer-coverage-trace-pc-guard \
|
||||||
; RUN: -S | FileCheck %s
|
; RUN: -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 \
|
||||||
|
; RUN: -sanitizer-coverage-stack-depth -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 \
|
||||||
|
; RUN: -sanitizer-coverage-stack-depth -sanitizer-coverage-trace-pc-guard \
|
||||||
|
; RUN: -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
; Test -sanitizer-coverage-trace-compares=1 (instrumenting a switch)
|
; Test -sanitizer-coverage-trace-compares=1 (instrumenting a switch)
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-compares=1 -S | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_TRACE_PC_GUARD
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_TRACE_PC_GUARD
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_TRACE_PC_GUARD
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-inline-8bit-counters -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-inline-8bit-counters -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=1 -sanitizer-coverage-trace-pc-guard -sanitizer-coverage-inline-8bit-counters -S | FileCheck %s
|
||||||
|
|
||||||
; Module ctors should have stable names across modules, not something like
|
; Module ctors should have stable names across modules, not something like
|
||||||
; @sancov.module_ctor.3 that may cause duplicate ctors after linked together.
|
; @sancov.module_ctor.3 that may cause duplicate ctors after linked together.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_TRACE_PC_GUARD
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_TRACE_PC_GUARD
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=4 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_TRACE_PC_GUARD
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-apple-darwin10.0.0"
|
target triple = "x86_64-apple-darwin10.0.0"
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
; Make sure asan does not instrument __sancov_gen_
|
; Make sure asan does not instrument __sancov_gen_
|
||||||
; RUN: opt < %s -sancov -asan -asan-module -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
; RUN: opt < %s -sancov -asan -asan-module -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
|
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='module(require<asan-globals-md>,sancov-module,asan-module),function(sancov-func,asan)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
$Foo = comdat any
|
$Foo = comdat any
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_PC_GUARD
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_PC_GUARD
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S -mtriple=x86_64-apple-macosx | FileCheck %s --check-prefix=CHECK_PC_GUARD_DARWIN
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S -mtriple=x86_64-apple-macosx | FileCheck %s --check-prefix=CHECK_PC_GUARD_DARWIN
|
||||||
|
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK_PC
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s --check-prefix=CHECK_PC_GUARD
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S -mtriple=x86_64-apple-macosx | FileCheck %s --check-prefix=CHECK_PC_GUARD_DARWIN
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
define void @foo(i32* %a) sanitize_address {
|
define void @foo(i32* %a) sanitize_address {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -S -sancov -sanitizer-coverage-level=3 | FileCheck %s
|
; RUN: opt < %s -S -sancov -sanitizer-coverage-level=3 | FileCheck %s
|
||||||
|
; RUN: opt < %s -S -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 | FileCheck %s
|
||||||
|
|
||||||
; The critical edges to unreachable_bb should not be split.
|
; The critical edges to unreachable_bb should not be split.
|
||||||
define i32 @foo(i32 %c, i32 %d) {
|
define i32 @foo(i32 %c, i32 %d) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK
|
; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK
|
||||||
|
; RUN: opt < %s -passes='module(sancov-module),function(sancov-func)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc -S | FileCheck %s --check-prefix=CHECK
|
||||||
|
|
||||||
; Generated from this C++ source:
|
; Generated from this C++ source:
|
||||||
; $ clang -O2 t.cpp -S -emit-llvm
|
; $ clang -O2 t.cpp -S -emit-llvm
|
||||||
|
|
Loading…
Reference in New Issue