blob: 20f6ec93eceb0b58932608ae67324374edbb4dbf [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.
Abhishek Arya31f18f52018-04-27 19:27:3496 config_file_name = target_name + ".options"
97 action(config_file_name) {
mmoroz344a75ae2016-03-02 16:57:1798 script = "//testing/libfuzzer/gen_fuzzer_config.py"
99 args = [
100 "--config",
Abhishek Arya31f18f52018-04-27 19:27:34101 rebase_path("$root_build_dir/" + config_file_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 = [
Abhishek Arya31f18f52018-04-27 19:27:34118 "$root_build_dir/$config_file_name",
mmoroz344a75ae2016-03-02 16:57:17119 ]
120 }
Abhishek Arya31f18f52018-04-27 19:27:34121 test_deps += [ ":" + config_file_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 Arya31f18f52018-04-27 19:27:34125 owners_file_name = target_name + ".owners"
126 action(owners_file_name) {
127 script = "//testing/libfuzzer/gen_fuzzer_owners.py"
128 args = [
129 "--owners",
130 rebase_path("$root_build_dir/" + owners_file_name, root_build_dir),
131 ]
Abhishek Aryae1488c922018-04-26 03:25:58132
Abhishek Arya31f18f52018-04-27 19:27:34133 if (defined(invoker.sources) && invoker.sources != []) {
134 args += [ "--sources" ] + rebase_path(invoker.sources, root_build_dir)
135 } else if (defined(invoker.deps) && invoker.deps != []) {
136 args += [
137 "--build-dir",
138 rebase_path("$root_build_dir/", root_build_dir),
139 "--deps",
140 ] + invoker.deps
Abhishek Aryae1488c922018-04-26 03:25:58141 }
Abhishek Arya31f18f52018-04-27 19:27:34142
143 outputs = [
144 "$root_build_dir/$owners_file_name",
145 ]
Abhishek Aryae1488c922018-04-26 03:25:58146 }
Abhishek Arya31f18f52018-04-27 19:27:34147 test_deps += [ ":" + owners_file_name ]
Abhishek Aryae1488c922018-04-26 03:25:58148
aizatsky43d459a52016-02-13 01:22:18149 test(target_name) {
150 forward_variables_from(invoker,
151 [
[email protected]419d0f92017-09-14 12:07:47152 "cflags",
153 "cflags_cc",
brettw6b0712a2016-07-15 17:48:20154 "check_includes",
wfhdee978f2016-09-01 22:18:18155 "defines",
aizatsky43d459a52016-02-13 01:22:18156 "include_dirs",
brettw6b0712a2016-07-15 17:48:20157 "sources",
aizatsky43d459a52016-02-13 01:22:18158 ])
159 deps = test_deps
aizatsky43d459a52016-02-13 01:22:18160
161 if (defined(invoker.additional_configs)) {
162 configs += invoker.additional_configs
163 }
aizatsky345732a2016-04-14 22:30:44164 configs += [ "//testing/libfuzzer:fuzzer_test_config" ]
katrielc2bfe70482016-06-16 13:43:00165
166 # Used by WebRTC to suppress some Clang warnings in their codebase.
167 if (defined(invoker.suppressed_configs)) {
168 configs -= invoker.suppressed_configs
169 }
Robert Sesekd88ebf82017-10-17 21:54:41170
171 if (is_mac) {
Max Morozae3aae52017-10-18 01:50:19172 sources += [ "//testing/libfuzzer/libfuzzer_exports.h" ]
Robert Sesekd88ebf82017-10-17 21:54:41173 }
aizatskycb1a43932015-12-14 20:59:14174 }
aizatsky43d459a52016-02-13 01:22:18175 } else {
176 # noop on unsupported platforms.
177 # mark attributes as used.
178 assert(invoker.sources == [] || invoker.sources != [])
aizatskycb1a43932015-12-14 20:59:14179 if (defined(invoker.additional_configs)) {
aizatsky43d459a52016-02-13 01:22:18180 assert(
181 invoker.additional_configs == [] || invoker.additional_configs != [])
182 }
183 if (defined(invoker.deps)) {
184 assert(invoker.deps == [] || invoker.deps != [])
185 }
186 if (defined(invoker.dict)) {
187 assert(invoker.dict == [] || invoker.dict != [])
188 }
mmoroz344a75ae2016-03-02 16:57:17189 if (defined(invoker.libfuzzer_options)) {
190 assert(invoker.libfuzzer_options == [] || invoker.libfuzzer_options != [])
191 }
aizatsky198e3022016-03-08 21:33:46192 if (defined(invoker.seed_corpus)) {
193 assert(invoker.seed_corpus == [] || invoker.seed_corpus != [])
194 }
mmoroz2d9411b2017-02-09 12:01:37195 if (defined(invoker.seed_corpuses)) {
196 assert(invoker.seed_corpuses == [] || invoker.seed_corpuses != [])
197 }
brettw6b0712a2016-07-15 17:48:20198 assert(!defined(invoker.check_includes) || invoker.check_includes != [])
wfhdee978f2016-09-01 22:18:18199 assert(!defined(invoker.include_dirs) || invoker.include_dirs != [])
200 assert(!defined(invoker.defines) || invoker.defines != [])
aizatsky43d459a52016-02-13 01:22:18201
202 group(target_name) {
aizatskycb1a43932015-12-14 20:59:14203 }
204 }
205}