From a125d1842742851a11f3517a0d0cabcff9a00aeb Mon Sep 17 00:00:00 2001
From: Aaron Green <aarongreen@google.com>
Date: Sat, 11 May 2019 11:03:24 +0000
Subject: [PATCH] [zircon][gn] Add fuzzer environments

This CL adds environments derived from the standard environments that
instrument code with '-fsanitize=fuzzer' and link against
libclang_rt.fuzzer.a.

Bug: SEC-251
Test: noop-test; see zircon/public/gn/toolchain/environment.gni
Change-Id: I7d25134b78eb2fbdead551599e15218b68ecd5ba
---
 zircon/BUILD.gn                               |  1 +
 .../public/gn/config/instrumentation/BUILD.gn | 38 ++++++++-------
 zircon/public/gn/fuzzer/BUILD.gn              | 46 +++++++++++++++++++
 3 files changed, 69 insertions(+), 16 deletions(-)
 create mode 100644 zircon/public/gn/fuzzer/BUILD.gn

diff --git a/zircon/BUILD.gn b/zircon/BUILD.gn
index 8b6a2e4e413..9195035a7ed 100644
--- a/zircon/BUILD.gn
+++ b/zircon/BUILD.gn
@@ -218,6 +218,7 @@ group("all-cpu") {
 group("build-tests") {
   testonly = true
   deps = [
+    "$zx/public/gn/fuzzer:noop-test.fuzzer",
     "$zx/public/gn/toolchain:noop-test",
   ]
 }
diff --git a/zircon/public/gn/config/instrumentation/BUILD.gn b/zircon/public/gn/config/instrumentation/BUILD.gn
index 9ea97513bfe..df0bfcff1e7 100644
--- a/zircon/public/gn/config/instrumentation/BUILD.gn
+++ b/zircon/public/gn/config/instrumentation/BUILD.gn
@@ -122,6 +122,28 @@ if (toolchain.tags + [ "sancov" ] - [ "sancov" ] != toolchain.tags) {
     cflags = compiler_flags
     ldflags = compiler_flags
   }
+
+  # fuzzer instrumentation is a superset of the sancov instrumentation.
+  config("fuzzer") {
+    compiler_flags = [ "-fsanitize=fuzzer" ]
+    asmflags = compiler_flags
+    cflags = compiler_flags
+    ldflags = compiler_flags
+
+    # TODO(TC-458): Include libunwind in libclang_rt.fuzzer.a
+    libs = [ "unwind" ]
+  }
+
+  group("fuzzer_deps") {
+    if (is_fuchsia) {
+      # The statically-linked libFuzzer runtime depends on libfdio and
+      # libzircon.
+      deps = [
+        "$zx/system/ulib/fdio",
+        "$zx/system/ulib/zircon",
+      ]
+    }
+  }
 }
 
 config("profile") {
@@ -142,19 +164,3 @@ group("profile_deps") {
     ]
   }
 }
-
-config("fuzzer") {
-  compiler_flags = [ "-fsanitize=fuzzer" ]
-  asmflags = compiler_flags
-  cflags = compiler_flags
-  ldflags = compiler_flags
-}
-
-group("fuzzer_deps") {
-  if (is_fuchsia) {
-    # The statically-linked libFuzzer runtime depends on libzircon.
-    deps = [
-      "$zx/system/ulib/zircon",
-    ]
-  }
-}
diff --git a/zircon/public/gn/fuzzer/BUILD.gn b/zircon/public/gn/fuzzer/BUILD.gn
new file mode 100644
index 00000000000..5855a7d8f7a
--- /dev/null
+++ b/zircon/public/gn/fuzzer/BUILD.gn
@@ -0,0 +1,46 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("$zx/public/gn/toolchain/environment.gni")
+
+# Fuzzer environments: These add libFuzzer instrumentation and hooks. These
+# hooks will be undefined in shared libraries, and provided by the compiler
+# runtime, which itself has an implicit dependency on libzircon.
+standard_environments(".fuzzer") {
+  # Everything is compiled with the fuzzer instrumentation.
+  # Each variant can add additional bug-detection instrumentation.
+  configs = [
+    "$zx/public/gn/config/instrumentation:fuzzer",
+    {
+      # libFuzzer can only be statically linked into each executable.
+      # Instrumented shared library code has dangling references to runtime
+      # symbols that will only be defined in the executable.
+      shlib = true
+      remove = [ "$zx/public/gn/config:no_undefined_symbols" ]
+    },
+  ]
+  implicit_deps = [
+    {
+      types = [ "executable" ]
+      add = [ "$zx/public/gn/config/instrumentation:fuzzer_deps" ]
+    },
+  ]
+
+  # Required by the above. See $zx/public/gn/config/instrumentation:fuzzer.
+  tags = [ "sancov" ]
+
+  toolchain_vars = {
+    # Trailing dot will get "$variant/" appended to locate shared libraries.
+    libprefix = "fuzzer."
+  }
+  variant_libprefix = true
+
+  # Support all the sanitizers plus the baseline variant (i.e. a fuzzer
+  # that only detects explicit failure reports in the code, or crashes).
+  variant_selectors = standard_sanitizer_variants + standard_base_variants
+
+  # GCC doesn't support the fuzzer config always added here, so prune
+  # it from the baseline list.
+  exclude_variant_tags = [ "gcc" ]
+}
-- 
GitLab