# Copyright 2018 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("//build/package.gni")

# TODO(aarongreen): SEC-224.  Add tests to catch fuzzer building/packaging
# regressions.

# Defines a fuzz target component
#
# The fuzz_target template is used to create components containing binaries
# which leverage LLVM's libFuzzer to perform fuzz testing.
#
# Parameters
#
#   sources (optional)
#     Usual GN meaning. If present, the list must include a file defining
#     `LLVMFuzzerTestOneInput`.
#
#   binary (optional)
#     [path] The path to the primary binary for the component. This can be
#     used to indicate a fuzz_target binary built in a different phase of the
#     build, e.g. in zircon.
#
#     NOTE: Exactly one of sources or binary must be set.
#
#   options (optional)
#     [list of strings] Each option is of the form "key=value" and indicates
#     command line options that the fuzzer should be invoked with. Valid keys
#     are libFuzzer options (https://llvm.org/docs/LibFuzzer.html#options).
#
#   dictionary (optional)
#     [file] If specified, a file containing inputs, one per line, that the
#     fuzzer will use to generate new mutations.
#
template("fuzz_target") {
  assert(
      (defined(invoker.binary) && !defined(invoker.sources)) ||
          (!defined(invoker.binary) || defined(invoker.sources)),
      "Exactly one of `binary` or `sources` must be defined for $target_name")
  fuzz_target_name = target_name

  # If not specified, generate the component binary
  if (!defined(invoker.binary)) {
    executable(fuzz_target_name) {
      # Explicitly forward visibility, implicitly forward everything else.
      # See comment in //build/config/BUILDCONFIG.gn for details on this pattern.
      forward_variables_from(invoker, [ "visibility" ])
      forward_variables_from(invoker,
                             "*",
                             [
                               "dictionary",
                               "options",
                               "visibility",
                             ])
      testonly = true
      _target_type = "fuzzed_executable"
    }
  }

  # Generate the component manifest
  fuzz_target_cmx = "${target_gen_dir}/${fuzz_target_name}.cmx"
  action("${fuzz_target_name}_cmx") {
    script = "//build/fuzzing/gen_fuzzer_manifest.py"
    outputs = [
      fuzz_target_cmx,
    ]
    args = [
      "--out",
      rebase_path(outputs[0]),
      "--bin",
    ]
    if (defined(invoker.binary)) {
      args += [ invoker.binary ]
    } else {
      args += [ fuzz_target_name ]
    }
    if (defined(invoker.cmx)) {
      args += [
        "--cmx",
        rebase_path(invoker.cmx),
      ]
    }
  }

  # Generate data files needed at runtime
  output_dictionary = "${target_gen_dir}/${fuzz_target_name}/dictionary"
  if (defined(invoker.dictionary)) {
    copy("${fuzz_target_name}_dictionary") {
      sources = [
        invoker.dictionary,
      ]
      outputs = [
        output_dictionary,
      ]
    }
  } else {
    generated_file("${fuzz_target_name}_dictionary") {
      contents = []
      outputs = [
        output_dictionary,
      ]
    }
  }
  generated_file("${fuzz_target_name}_options") {
    contents = []
    if (defined(invoker.options)) {
      contents = invoker.options
    }
    outputs = [
      "${target_gen_dir}/${fuzz_target_name}/options",
    ]
  }

  # Create the fuzz_target component
  fuchsia_component("${fuzz_target_name}_component") {
    testonly = true
    manifest = fuzz_target_cmx
    if (defined(invoker.binary)) {
      binary = invoker.binary
    } else {
      binary = "${fuzz_target_name}"
    }
    resources = [
      {
        path = "${target_gen_dir}/${fuzz_target_name}/dictionary"
        dest = "${fuzz_target_name}/dictionary"
      },
      {
        path = "${target_gen_dir}/${fuzz_target_name}/options"
        dest = "${fuzz_target_name}/options"
      },
    ]
    deps = []
    forward_variables_from(invoker, [ "visibility" ])
    if (!defined(invoker.binary)) {
      # deps, public_deps, and data_deps are forwarded to ${fuzz_target_name}
      deps += [ ":${fuzz_target_name}" ]
    } else {
      forward_variables_from(invoker,
                             [
                               "deps",
                               "public_deps",
                               "data_deps",
                             ])
    }
    deps += [
      ":${fuzz_target_name}_cmx",
      ":${fuzz_target_name}_dictionary",
      ":${fuzz_target_name}_options",
    ]
  }
}

set_defaults("fuzz_target") {
  configs = default_executable_configs +
            [ "//build/fuzzing:fuzzing_build_mode_unsafe_for_production" ]
}

# Defines a package of fuzz target components
#
# The fuzz_package template is used to bundle several fuzz_targets and their
# associated data into a single Fuchsia package.
#
# Parameters
#
#   targets (required)
#     [list of labels] The fuzz_target() targets to include in this package.
#
#   sanitizers (optional)
#     [list of variants] A set of sanitizer variants.  The resulting package
#     will contain binaries for each sanitizer/target combination. Defaults to
#     [ "asan", "ubsan" ]
#
#   fuzz_host (optional)
#     [boolean] Indicates whether to also build fuzzer binaries on host.
#     Defaults to false.
#
#   meta (optional)
#   binaries (optional)
#   components (optional)
#   tests (optional)
#   drivers (optional)
#   loadable_modules (optional)
#   resources (optional)
#   extra (optional)
#     Same meanings as in //build/package.gni
#
#   deps (optional)
#   public_deps (optional)
#   data_deps (optional)
#   testonly (optional)
#     Usual GN meanings.
template("fuzz_package") {
  assert(defined(invoker.targets), "targets must be defined for $target_name}")

  if (defined(invoker.sanitizers)) {
    sanitizers = invoker.sanitizers
  } else {
    sanitizers = [
      "asan",
      "ubsan",
    ]
  }

  # Collect the selected fuzz targets listed in this package based on the
  # variants selected in args.gn and filtered by the package's list of
  # supported sanitizers.
  selected_targets = []
  foreach(fuzz_target, invoker.targets) {
    selected = false
    foreach(sanitizer, sanitizers) {
      foreach(selector, select_variant_canonical) {
        if (!selected && selector.variant == "${sanitizer}-fuzzer" &&
            ((defined(selector.target_type) &&
              selector.target_type == [ "fuzzed_executable" ]) ||
             (defined(selector.name) && selector.name == [ fuzz_target ]) ||
             (defined(selector.output_name) &&
              selector.output_name == [ fuzz_target ]))) {
          selected = true
          selected_targets += [ fuzz_target ]
        }
      }
    }

    # When no variants are present, `selected` is unused.
    not_needed([ "selected" ])
  }

  # Assemble the Fuchsia package
  if (selected_targets != []) {
    package(target_name) {
      metadata = {
        fuzz_spec = [
          {
            fuzz_package = target_name
            fuzz_targets = []
            foreach(selected_target, selected_targets) {
              fuzz_targets += [ get_label_info(selected_target, "name") ]
            }
          },
        ]
        if (defined(invoker.metadata)) {
          forward_variables_from(invoker.metadata, "*", [ "fuzz_spec" ])
        }
      }
      components = []
      forward_variables_from(invoker, [ "visibility" ])
      forward_variables_from(invoker,
                             "*",
                             [
                               "targets",
                               "sanitizers",
                               "visibility",
                               "fuzz_host",
                             ])
      testonly = true
      foreach(selected_target, selected_targets) {
        components += [ "${selected_target}_component" ]
      }
    }
  } else {
    # Dummy package for non-fuzzed builds
    group(target_name) {
    }
    not_needed(invoker, "*")
  }

  # Create a (possibly empty) target for host fuzzers
  group("host_${target_name}") {
    testonly = true
    if (defined(invoker.fuzz_host) && invoker.fuzz_host) {
      deps = selected_targets
    }
  }
}
