forked from OSchip/llvm-project
[SanitizerCoverage] Add -fsanitize-coverage=inline-bool-flag
Reviewers: kcc, vitalybuka Reviewed By: vitalybuka Subscribers: cfe-commits, llvm-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77637
This commit is contained in:
parent
9c7bd94ce8
commit
ced398fdc8
|
@ -139,6 +139,28 @@ Users need to implement a single function to capture the counters at startup.
|
|||
// Capture this array in order to read/modify the counters.
|
||||
}
|
||||
|
||||
|
||||
Inline bool-flag
|
||||
================
|
||||
|
||||
**Experimental, may change or disappear in future**
|
||||
|
||||
With ``-fsanitize-coverage=inline-bool-flag`` the compiler will insert
|
||||
setting an inline boolean to true on every edge.
|
||||
This is similar to ``-fsanitize-coverage=inline-8bit-counter`` but instead of
|
||||
an increment of a counter, it just sets a boolean to true.
|
||||
|
||||
Users need to implement a single function to capture the flags at startup.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
extern "C"
|
||||
void __sanitizer_cov_bool_flag_init(bool *start, bool *end) {
|
||||
// [start,end) is the array of boolean flags created for the current DSO.
|
||||
// Capture this array in order to read/modify the flags.
|
||||
}
|
||||
|
||||
|
||||
PC-Table
|
||||
========
|
||||
|
||||
|
@ -150,8 +172,8 @@ significant binary size overhead. For more information, see
|
|||
`Bug 34636 <https://bugs.llvm.org/show_bug.cgi?id=34636>`_.
|
||||
|
||||
With ``-fsanitize-coverage=pc-table`` the compiler will create a table of
|
||||
instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters`` or
|
||||
``-fsanitize-coverage=trace-pc-guard``.
|
||||
instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters``,
|
||||
or ``-fsanitize-coverage=inline-bool-flag``, or ``-fsanitize-coverage=trace-pc-guard``.
|
||||
|
||||
Users need to implement a single function to capture the PC table at startup:
|
||||
|
||||
|
@ -164,8 +186,9 @@ Users need to implement a single function to capture the PC table at startup:
|
|||
// pairs [PC,PCFlags] for every instrumented block in the current DSO.
|
||||
// Capture this array in order to read the PCs and their Flags.
|
||||
// The number of PCs and PCFlags for a given DSO is the same as the number
|
||||
// of 8-bit counters (-fsanitize-coverage=inline-8bit-counters) or
|
||||
// trace_pc_guard callbacks (-fsanitize-coverage=trace-pc-guard)
|
||||
// of 8-bit counters (-fsanitize-coverage=inline-8bit-counters), or
|
||||
// boolean flags (-fsanitize-coverage=inline=bool-flags), or trace_pc_guard
|
||||
// callbacks (-fsanitize-coverage=trace-pc-guard).
|
||||
// A PCFlags describes the basic block:
|
||||
// * bit0: 1 if the block is the function entry block, 0 otherwise.
|
||||
}
|
||||
|
|
|
@ -232,6 +232,7 @@ CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
|
|||
CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
|
||||
///< in sanitizer coverage.
|
||||
CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters.
|
||||
CODEGENOPT(SanitizeCoverageInlineBoolFlag, 1, 0) ///< Use inline bool flag.
|
||||
CODEGENOPT(SanitizeCoveragePCTable, 1, 0) ///< Create a PC Table.
|
||||
CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
|
||||
CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
|
||||
|
|
|
@ -355,6 +355,9 @@ def fsanitize_coverage_8bit_counters
|
|||
def fsanitize_coverage_inline_8bit_counters
|
||||
: Flag<["-"], "fsanitize-coverage-inline-8bit-counters">,
|
||||
HelpText<"Enable inline 8-bit counters in sanitizer coverage">;
|
||||
def fsanitize_coverage_inline_bool_flag
|
||||
: Flag<["-"], "fsanitize-coverage-inline-bool-flag">,
|
||||
HelpText<"Enable inline bool flag in sanitizer coverage">;
|
||||
def fsanitize_coverage_pc_table
|
||||
: Flag<["-"], "fsanitize-coverage-pc-table">,
|
||||
HelpText<"Create a table of coverage-instrumented PCs">;
|
||||
|
|
|
@ -901,7 +901,7 @@ def fdiagnostics_hotness_threshold_EQ : Joined<["-"], "fdiagnostics-hotness-thre
|
|||
def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
|
||||
HelpText<"Print option name with mappable diagnostics">;
|
||||
def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
|
||||
Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
|
||||
Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
|
||||
def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>;
|
||||
def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<f_clang_Group>;
|
||||
def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">,
|
||||
|
@ -1019,7 +1019,7 @@ def fno_sanitize_coverage
|
|||
: CommaJoined<["-"], "fno-sanitize-coverage=">,
|
||||
Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable specified features of coverage instrumentation for "
|
||||
"Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters">;
|
||||
"Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters,inline-bool-flag">;
|
||||
def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable origins tracking in MemorySanitizer">;
|
||||
|
|
|
@ -222,6 +222,7 @@ getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts) {
|
|||
Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
|
||||
Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
|
||||
Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
|
||||
Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
|
||||
Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
|
||||
Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
|
||||
return Opts;
|
||||
|
|
|
@ -77,17 +77,18 @@ enum CoverageFeature {
|
|||
CoverageBB = 1 << 1,
|
||||
CoverageEdge = 1 << 2,
|
||||
CoverageIndirCall = 1 << 3,
|
||||
CoverageTraceBB = 1 << 4, // Deprecated.
|
||||
CoverageTraceBB = 1 << 4, // Deprecated.
|
||||
CoverageTraceCmp = 1 << 5,
|
||||
CoverageTraceDiv = 1 << 6,
|
||||
CoverageTraceGep = 1 << 7,
|
||||
Coverage8bitCounters = 1 << 8, // Deprecated.
|
||||
Coverage8bitCounters = 1 << 8, // Deprecated.
|
||||
CoverageTracePC = 1 << 9,
|
||||
CoverageTracePCGuard = 1 << 10,
|
||||
CoverageNoPrune = 1 << 11,
|
||||
CoverageInline8bitCounters = 1 << 12,
|
||||
CoveragePCTable = 1 << 13,
|
||||
CoverageStackDepth = 1 << 14,
|
||||
CoverageInlineBoolFlag = 1 << 15,
|
||||
};
|
||||
|
||||
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
|
||||
|
@ -723,8 +724,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
<< "-fsanitize-coverage=trace-pc-guard";
|
||||
|
||||
int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
|
||||
int InstrumentationTypes =
|
||||
CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters;
|
||||
int InstrumentationTypes = CoverageTracePC | CoverageTracePCGuard |
|
||||
CoverageInline8bitCounters |
|
||||
CoverageInlineBoolFlag;
|
||||
if ((CoverageFeatures & InsertionPointTypes) &&
|
||||
!(CoverageFeatures & InstrumentationTypes)) {
|
||||
D.Diag(clang::diag::warn_drv_deprecated_arg)
|
||||
|
@ -735,7 +737,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
// trace-pc w/o func/bb/edge implies edge.
|
||||
if (!(CoverageFeatures & InsertionPointTypes)) {
|
||||
if (CoverageFeatures &
|
||||
(CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters))
|
||||
(CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters |
|
||||
CoverageInlineBoolFlag))
|
||||
CoverageFeatures |= CoverageEdge;
|
||||
|
||||
if (CoverageFeatures & CoverageStackDepth)
|
||||
|
@ -907,21 +910,25 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
|||
// Do it even if Sanitizers.empty() since some forms of coverage don't require
|
||||
// sanitizers.
|
||||
std::pair<int, const char *> CoverageFlags[] = {
|
||||
std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
|
||||
std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
|
||||
std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
|
||||
std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
|
||||
std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
|
||||
std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
|
||||
std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
|
||||
std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
|
||||
std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
|
||||
std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
|
||||
std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
|
||||
std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"),
|
||||
std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
|
||||
std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
|
||||
std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
|
||||
std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
|
||||
std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
|
||||
std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
|
||||
std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
|
||||
std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
|
||||
std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
|
||||
std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
|
||||
std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
|
||||
std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
|
||||
std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
|
||||
std::make_pair(CoverageTracePCGuard,
|
||||
"-fsanitize-coverage-trace-pc-guard"),
|
||||
std::make_pair(CoverageInline8bitCounters,
|
||||
"-fsanitize-coverage-inline-8bit-counters"),
|
||||
std::make_pair(CoverageInlineBoolFlag,
|
||||
"-fsanitize-coverage-inline-bool-flag"),
|
||||
std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
|
||||
std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
|
||||
std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
|
||||
for (auto F : CoverageFlags) {
|
||||
if (CoverageFeatures & F.first)
|
||||
CmdArgs.push_back(F.second);
|
||||
|
@ -1105,22 +1112,23 @@ int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
|
|||
for (int i = 0, n = A->getNumValues(); i != n; ++i) {
|
||||
const char *Value = A->getValue(i);
|
||||
int F = llvm::StringSwitch<int>(Value)
|
||||
.Case("func", CoverageFunc)
|
||||
.Case("bb", CoverageBB)
|
||||
.Case("edge", CoverageEdge)
|
||||
.Case("indirect-calls", CoverageIndirCall)
|
||||
.Case("trace-bb", CoverageTraceBB)
|
||||
.Case("trace-cmp", CoverageTraceCmp)
|
||||
.Case("trace-div", CoverageTraceDiv)
|
||||
.Case("trace-gep", CoverageTraceGep)
|
||||
.Case("8bit-counters", Coverage8bitCounters)
|
||||
.Case("trace-pc", CoverageTracePC)
|
||||
.Case("trace-pc-guard", CoverageTracePCGuard)
|
||||
.Case("no-prune", CoverageNoPrune)
|
||||
.Case("inline-8bit-counters", CoverageInline8bitCounters)
|
||||
.Case("pc-table", CoveragePCTable)
|
||||
.Case("stack-depth", CoverageStackDepth)
|
||||
.Default(0);
|
||||
.Case("func", CoverageFunc)
|
||||
.Case("bb", CoverageBB)
|
||||
.Case("edge", CoverageEdge)
|
||||
.Case("indirect-calls", CoverageIndirCall)
|
||||
.Case("trace-bb", CoverageTraceBB)
|
||||
.Case("trace-cmp", CoverageTraceCmp)
|
||||
.Case("trace-div", CoverageTraceDiv)
|
||||
.Case("trace-gep", CoverageTraceGep)
|
||||
.Case("8bit-counters", Coverage8bitCounters)
|
||||
.Case("trace-pc", CoverageTracePC)
|
||||
.Case("trace-pc-guard", CoverageTracePCGuard)
|
||||
.Case("no-prune", CoverageNoPrune)
|
||||
.Case("inline-8bit-counters", CoverageInline8bitCounters)
|
||||
.Case("inline-bool-flag", CoverageInlineBoolFlag)
|
||||
.Case("pc-table", CoveragePCTable)
|
||||
.Case("stack-depth", CoverageStackDepth)
|
||||
.Default(0);
|
||||
if (F == 0)
|
||||
D.Diag(clang::diag::err_drv_unsupported_option_argument)
|
||||
<< A->getOption().getName() << Value;
|
||||
|
|
|
@ -1176,6 +1176,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
|||
Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune);
|
||||
Opts.SanitizeCoverageInline8bitCounters =
|
||||
Args.hasArg(OPT_fsanitize_coverage_inline_8bit_counters);
|
||||
Opts.SanitizeCoverageInlineBoolFlag =
|
||||
Args.hasArg(OPT_fsanitize_coverage_inline_bool_flag);
|
||||
Opts.SanitizeCoveragePCTable = Args.hasArg(OPT_fsanitize_coverage_pc_table);
|
||||
Opts.SanitizeCoverageStackDepth =
|
||||
Args.hasArg(OPT_fsanitize_coverage_stack_depth);
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
// FNOSANICOVERALL-NEXT: func
|
||||
// FNOSANICOVERALL-NEXT: indirect-calls
|
||||
// FNOSANICOVERALL-NEXT: inline-8bit-counters
|
||||
// FNOSANICOVERALL-NEXT: inline-bool-flag
|
||||
// FNOSANICOVERALL-NEXT: no-prune
|
||||
// FNOSANICOVERALL-NEXT: trace-bb
|
||||
// FNOSANICOVERALL-NEXT: trace-cmp
|
||||
|
|
|
@ -105,9 +105,18 @@
|
|||
// CHECK_INLINE8BIT-NOT: warning
|
||||
// CHECK_INLINE8BIT: -fsanitize-coverage-inline-8bit-counters
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE
|
||||
// CHECK_PC_TABLE: -fsanitize-coverage-pc-table
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT
|
||||
// CHECK_PC_TABLE_FOR_INLINE8BIT: -fsanitize-coverage-pc-table
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=bb,inline-bool-flag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG
|
||||
// CHECK_INLINE_BOOL_FLAG-NOT: warning
|
||||
// CHECK_INLINE_BOOL_FLAG: -fsanitize-coverage-inline-bool-flag
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL
|
||||
// CHECK_PC_TABLE_FOR_INLINEBOOL: -fsanitize-coverage-pc-table
|
||||
|
||||
// RUN: %clang_cl --target=i386-pc-win32 -fsanitize=address -fsanitize-coverage=func,trace-pc-guard -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE
|
||||
// CLANG-CL-COVERAGE-NOT: error:
|
||||
|
|
Loading…
Reference in New Issue