blob: 7fe926dcb85f60cadf56d7fb6937948b53fc4971 [file] [log] [blame]
aizatskycb1a43932015-12-14 20:59:141# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
aizatsky7dfb57342015-12-21 04:02:525# Defines fuzzer_test.
6#
Max Moroz915eb5a2018-04-24 16:10:357import("//build/config/coverage/coverage.gni")
aizatsky43d459a52016-02-13 01:22:188import("//build/config/features.gni")
9import("//build/config/sanitizers/sanitizers.gni")
aizatskycb1a43932015-12-14 20:59:1410import("//testing/test.gni")
11
12# fuzzer_test is used to define individual libfuzzer tests.
13#
14# Supported attributes:
15# - (required) sources - fuzzer test source files
aizatskycb1a43932015-12-14 20:59:1416# - deps - test dependencies
17# - additional_configs - additional configs to be used for compilation
18# - dict - a dictionary file for the fuzzer.
mmoroz344a75ae2016-03-02 16:57:1719# - libfuzzer_options - options for the fuzzer (e.g. -max_len or -timeout).
aizatsky198e3022016-03-08 21:33:4620# - seed_corpus - a directory with seed corpus.
Abhishek Aryac73294d2018-04-26 22:12:4321# - skip_owners - if true, skips writing the owners file.
aizatskycb1a43932015-12-14 20:59:1422#
aizatsky43d459a52016-02-13 01:22:1823# If use_libfuzzer gn flag is defined, then proper fuzzer would be build.
metzman8c9ed0e2016-06-21 20:37:2024# Without use_libfuzzer or use_afl a unit-test style binary would be built on
25# linux and the whole target is a no-op otherwise.
aizatsky43d459a52016-02-13 01:22:1826#
aizatskycb1a43932015-12-14 20:59:1427# The template wraps test() target with appropriate dependencies.
mmoroz344a75ae2016-03-02 16:57:1728# If any test run-time options are present (dict or libfuzzer_options), then a
29# config (.options file) file would be generated or modified in root output
aizatskycb1a43932015-12-14 20:59:1430# dir (next to test).
31template("fuzzer_test") {
Max Moroz915eb5a2018-04-24 16:10:3532 assert(!(is_mac && use_clang_coverage && use_fuzzing_engine),
33 "Code Coverage for fuzz targets does not work on Mac until " +
34 "crbug.com/790747 is resolved.")
35
Jonathan Metzmand901d1b2017-10-09 23:07:2836 if (!disable_libfuzzer && (use_fuzzing_engine || use_drfuzz || is_linux)) {
aizatsky43d459a52016-02-13 01:22:1837 assert(defined(invoker.sources), "Need sources in $target_name.")
aizatskycb1a43932015-12-14 20:59:1438
aizatsky43d459a52016-02-13 01:22:1839 test_deps = [ "//testing/libfuzzer:libfuzzer_main" ]
aizatskycb1a43932015-12-14 20:59:1440
aizatsky43d459a52016-02-13 01:22:1841 if (defined(invoker.deps)) {
42 test_deps += invoker.deps
43 }
aizatskycb1a43932015-12-14 20:59:1444
mmoroz902ef432017-02-07 17:03:3745 if (defined(invoker.seed_corpus) || defined(invoker.seed_corpuses)) {
46 assert(!(defined(invoker.seed_corpus) && defined(invoker.seed_corpuses)),
47 "Do not use both seed_corpus and seed_corpuses for $target_name.")
48
aizatsky198e3022016-03-08 21:33:4649 out = "$root_build_dir/$target_name" + "_seed_corpus.zip"
50
51 action(target_name + "_seed_corpus") {
52 script = "//testing/libfuzzer/archive_corpus.py"
mmoroz902ef432017-02-07 17:03:3753
aizatsky198e3022016-03-08 21:33:4654 args = [
aizatsky198e3022016-03-08 21:33:4655 "--output",
wychen5e1f7252017-05-30 08:05:1056 rebase_path(out, root_build_dir),
aizatsky198e3022016-03-08 21:33:4657 ]
58
mmoroz902ef432017-02-07 17:03:3759 if (defined(invoker.seed_corpus)) {
wychen5e1f7252017-05-30 08:05:1060 args += [ rebase_path(invoker.seed_corpus, root_build_dir) ]
mmoroz902ef432017-02-07 17:03:3761 }
62
63 if (defined(invoker.seed_corpuses)) {
64 foreach(seed_corpus_path, invoker.seed_corpuses) {
wychen5e1f7252017-05-30 08:05:1065 args += [ rebase_path(seed_corpus_path, root_build_dir) ]
mmoroz902ef432017-02-07 17:03:3766 }
67 }
68
aizatsky198e3022016-03-08 21:33:4669 outputs = [
70 out,
71 ]
mmoroz902ef432017-02-07 17:03:3772
aizatsky7951d34f2016-03-11 00:09:4573 deps = [
74 "//testing/libfuzzer:seed_corpus",
75 ]
aizatsky198e3022016-03-08 21:33:4676 }
77
78 test_deps += [ ":" + target_name + "_seed_corpus" ]
79 }
80
mmoroz062a4a62016-04-12 09:02:3381 if (defined(invoker.dict) || defined(invoker.libfuzzer_options)) {
82 if (defined(invoker.dict)) {
83 # Copy dictionary to output.
84 copy(target_name + "_dict_copy") {
85 sources = [
86 invoker.dict,
87 ]
88 outputs = [
89 "$root_build_dir/" + target_name + ".dict",
90 ]
91 }
92 test_deps += [ ":" + target_name + "_dict_copy" ]
aizatsky43d459a52016-02-13 01:22:1893 }
94
mmoroz062a4a62016-04-12 09:02:3395 # Generate .options file.
mmoroz344a75ae2016-03-02 16:57:1796 config_name = target_name + ".options"
97 action(config_name) {
98 script = "//testing/libfuzzer/gen_fuzzer_config.py"
99 args = [
100 "--config",
wychen5e1f7252017-05-30 08:05:10101 rebase_path("$root_build_dir/" + config_name, root_build_dir),
mmoroz344a75ae2016-03-02 16:57:17102 ]
103
mmoroz062a4a62016-04-12 09:02:33104 if (defined(invoker.dict)) {
mmoroz344a75ae2016-03-02 16:57:17105 args += [
mmoroz062a4a62016-04-12 09:02:33106 "--dict",
wychen5e1f7252017-05-30 08:05:10107 rebase_path("$root_build_dir/" + invoker.target_name + ".dict",
108 root_build_dir),
mmoroz344a75ae2016-03-02 16:57:17109 ]
110 }
mmoroz062a4a62016-04-12 09:02:33111
112 if (defined(invoker.libfuzzer_options)) {
113 args += [ "--libfuzzer_options" ]
114 args += invoker.libfuzzer_options
115 }
116
mmoroz344a75ae2016-03-02 16:57:17117 outputs = [
118 "$root_build_dir/$config_name",
119 ]
120 }
121 test_deps += [ ":" + config_name ]
aizatskycb1a43932015-12-14 20:59:14122 }
123
Abhishek Aryac73294d2018-04-26 22:12:43124 # Generate .owners file (if skip_owners is not true).
Abhishek Aryae1488c922018-04-26 03:25:58125 # FIXME: Add support for sources parsing in deps attribute.
Abhishek Aryac73294d2018-04-26 22:12:43126 if (invoker.sources != [] &&
127 (!defined(invoker.skip_owners) || !invoker.skip_owners)) {
Abhishek Aryae1488c922018-04-26 03:25:58128 owners_name = target_name + ".owners"
129 action(owners_name) {
130 script = "//testing/libfuzzer/gen_fuzzer_owners.py"
131 args = [
132 "--owners",
133 rebase_path("$root_build_dir/" + owners_name, root_build_dir),
134 "--sources",
135 ]
136 args += rebase_path(invoker.sources, root_build_dir)
137
138 outputs = [
139 "$root_build_dir/$owners_name",
140 ]
141 }
142 test_deps += [ ":" + owners_name ]
143 }
144
aizatsky43d459a52016-02-13 01:22:18145 test(target_name) {
146 forward_variables_from(invoker,
147 [
[email protected]419d0f92017-09-14 12:07:47148 "cflags",
149 "cflags_cc",
brettw6b0712a2016-07-15 17:48:20150 "check_includes",
wfhdee978f2016-09-01 22:18:18151 "defines",
aizatsky43d459a52016-02-13 01:22:18152 "include_dirs",
brettw6b0712a2016-07-15 17:48:20153 "sources",
aizatsky43d459a52016-02-13 01:22:18154 ])
155 deps = test_deps
aizatsky43d459a52016-02-13 01:22:18156
157 if (defined(invoker.additional_configs)) {
158 configs += invoker.additional_configs
159 }
aizatsky345732a2016-04-14 22:30:44160 configs += [ "//testing/libfuzzer:fuzzer_test_config" ]
katrielc2bfe70482016-06-16 13:43:00161
162 # Used by WebRTC to suppress some Clang warnings in their codebase.
163 if (defined(invoker.suppressed_configs)) {
164 configs -= invoker.suppressed_configs
165 }
Robert Sesekd88ebf82017-10-17 21:54:41166
167 if (is_mac) {
Max Morozae3aae52017-10-18 01:50:19168 sources += [ "//testing/libfuzzer/libfuzzer_exports.h" ]
Robert Sesekd88ebf82017-10-17 21:54:41169 }
aizatskycb1a43932015-12-14 20:59:14170 }
aizatsky43d459a52016-02-13 01:22:18171 } else {
172 # noop on unsupported platforms.
173 # mark attributes as used.
174 assert(invoker.sources == [] || invoker.sources != [])
aizatskycb1a43932015-12-14 20:59:14175 if (defined(invoker.additional_configs)) {
aizatsky43d459a52016-02-13 01:22:18176 assert(
177 invoker.additional_configs == [] || invoker.additional_configs != [])
178 }
179 if (defined(invoker.deps)) {
180 assert(invoker.deps == [] || invoker.deps != [])
181 }
182 if (defined(invoker.dict)) {
183 assert(invoker.dict == [] || invoker.dict != [])
184 }
mmoroz344a75ae2016-03-02 16:57:17185 if (defined(invoker.libfuzzer_options)) {
186 assert(invoker.libfuzzer_options == [] || invoker.libfuzzer_options != [])
187 }
aizatsky198e3022016-03-08 21:33:46188 if (defined(invoker.seed_corpus)) {
189 assert(invoker.seed_corpus == [] || invoker.seed_corpus != [])
190 }
mmoroz2d9411b2017-02-09 12:01:37191 if (defined(invoker.seed_corpuses)) {
192 assert(invoker.seed_corpuses == [] || invoker.seed_corpuses != [])
193 }
brettw6b0712a2016-07-15 17:48:20194 assert(!defined(invoker.check_includes) || invoker.check_includes != [])
wfhdee978f2016-09-01 22:18:18195 assert(!defined(invoker.include_dirs) || invoker.include_dirs != [])
196 assert(!defined(invoker.defines) || invoker.defines != [])
aizatsky43d459a52016-02-13 01:22:18197
198 group(target_name) {
aizatskycb1a43932015-12-14 20:59:14199 }
200 }
201}