]> granicus.if.org Git - clang/commitdiff
[sanitizer-coverage] implement -fsanitize-coverage=trace-pc. This is similar to trace...
authorKostya Serebryany <kcc@google.com>
Wed, 17 Feb 2016 21:34:43 +0000 (21:34 +0000)
committerKostya Serebryany <kcc@google.com>
Wed, 17 Feb 2016 21:34:43 +0000 (21:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261159 91177308-0d34-0410-b5e6-96231b3b80d8

docs/SanitizerCoverage.rst
include/clang/Driver/CC1Options.td
include/clang/Frontend/CodeGenOptions.def
lib/CodeGen/BackendUtil.cpp
lib/Driver/SanitizerArgs.cpp
lib/Frontend/CompilerInvocation.cpp
test/Driver/fsanitize-coverage.c

index 0e493400b4ec014616438ca4bf730af6121eac15..6d6e576e464506662f8bb9029b8238f35a386017 100644 (file)
@@ -291,6 +291,17 @@ With ``-fsanitize-coverage=trace-bb`` the compiler will insert
 ``__sanitizer_cov_trace_basic_block(s32 *id)`` before every function, basic block, or edge
 (depending on the value of ``-fsanitize-coverage=[func,bb,edge]``).
 
+Tracing PCs
+===========
+*Experimental* feature similar to tracing basic blocks, but with a different API.
+With ``-fsanitize-coverage=[func,bb,edge],trace-pc`` the compiler will insert
+``__sanitizer_cov_trace_pc()`` on every function/block/edge.
+With and additional ``indirect-calls`` flag
+``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.
+These callbacks are not implemented in the Sanitizer run-time and should be defined
+by the user.
+This mechanism is used for fuzzing the Linux kernel (https://github.com/google/syzkaller).
+
 Tracing data flow
 =================
 
index c1c4035016c8b4fc4a180d18c5a0379177a06be2..00ca505afd23436f897e92d3f527d0bb0b00da9b 100644 (file)
@@ -270,6 +270,9 @@ def fsanitize_coverage_trace_cmp
 def fsanitize_coverage_8bit_counters
     : Flag<["-"], "fsanitize-coverage-8bit-counters">,
       HelpText<"Enable frequency counters in sanitizer coverage">;
+def fsanitize_coverage_trace_pc
+    : Flag<["-"], "fsanitize-coverage-trace-pc">,
+      HelpText<"Enable PC tracing in sanitizer coverage">;
 def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
     HelpText<"Enable PGO instrumentation. The accepted values is clang or "
              "none">;
index 4b89ee3201640cd45c9a31e012125fed6d747628..bffe85bdbdab7528e40efa78b65ef84247b9f0a5 100644 (file)
@@ -134,6 +134,8 @@ CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing
                                            ///< in sanitizer coverage.
 CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters
                                                ///< in sanitizer coverage.
+CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing
+                                          ///< in sanitizer coverage.
 CODEGENOPT(SanitizeStats     , 1, 0) ///< Collect statistics for sanitizers.
 CODEGENOPT(SimplifyLibCalls  , 1, 1) ///< Set when -fbuiltin is enabled.
 CODEGENOPT(SoftFloat         , 1, 0) ///< -soft-float.
index 0cb039bb07acdf1c4d3d4f793979aa36cd09edb1..f5afc68eddc11626b93a2c8bc72d5dc5fb1fa2ce 100644 (file)
@@ -189,6 +189,7 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
   Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
   Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
   Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
+  Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
   PM.add(createSanitizerCoverageModulePass(Opts));
 }
 
index cf8d39d6efebdd8396f00e1c5ea2f727d93c203d..1614ee439c2ed929cc1e8d3b82ccaaac379d7a41 100644 (file)
@@ -49,6 +49,7 @@ enum CoverageFeature {
   CoverageTraceBB = 1 << 4,
   CoverageTraceCmp = 1 << 5,
   Coverage8bitCounters = 1 << 6,
+  CoverageTracePC = 1 << 7,
 };
 
 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
@@ -498,6 +499,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
     D.Diag(clang::diag::err_drv_argument_only_allowed_with)
         << "-fsanitize-coverage=8bit-counters"
         << "-fsanitize-coverage=(func|bb|edge)";
+  if ((CoverageFeatures & CoverageTracePC) &&
+      !(CoverageFeatures & CoverageTypes))
+    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+        << "-fsanitize-coverage=trace-pc"
+        << "-fsanitize-coverage=(func|bb|edge)";
 
   if (AllAddedKinds & Address) {
     AsanSharedRuntime =
@@ -615,7 +621,8 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
     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(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters")};
+    std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
+    std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc")};
   for (auto F : CoverageFlags) {
     if (CoverageFeatures & F.first)
       CmdArgs.push_back(Args.MakeArgString(F.second));
@@ -696,6 +703,7 @@ int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
         .Case("trace-bb", CoverageTraceBB)
         .Case("trace-cmp", CoverageTraceCmp)
         .Case("8bit-counters", Coverage8bitCounters)
+        .Case("trace-pc", CoverageTracePC)
         .Default(0);
     if (F == 0)
       D.Diag(clang::diag::err_drv_unsupported_option_argument)
index 2b191ca8dc3b40534e4db286a2a5757c8daa9c2b..c822bccaa3cab951c496bb28e8c0670dbd0ceb6d 100644 (file)
@@ -637,6 +637,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.SanitizeCoverageTraceCmp = Args.hasArg(OPT_fsanitize_coverage_trace_cmp);
   Opts.SanitizeCoverage8bitCounters =
       Args.hasArg(OPT_fsanitize_coverage_8bit_counters);
+  Opts.SanitizeCoverageTracePC = Args.hasArg(OPT_fsanitize_coverage_trace_pc);
   Opts.SanitizeMemoryTrackOrigins =
       getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
   Opts.SanitizeMemoryUseAfterDtor =
index fdaa9faf8902eb4f60e52e8789b854d1afcd2708..8ad20f1b9d8e6ce6a116ce4b324130fd5f14bcbd 100644 (file)
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=1 -fno-sanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-SAN-DISABLED
 // CHECK-SANITIZE-COVERAGE-SAN-DISABLED-NOT: argument unused
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge,indirect-calls,trace-bb,trace-cmp,8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FEATURES
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge,indirect-calls,trace-bb,trace-pc,trace-cmp,8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FEATURES
 // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-type=3
 // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-indirect-calls
 // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-trace-bb
 // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-trace-cmp
 // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-8bit-counters
+// CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-trace-pc
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,edge,indirect-calls,trace-bb,trace-cmp -fno-sanitize-coverage=edge,indirect-calls,trace-bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MASK
 // CHECK-MASK: -fsanitize-coverage-type=1