blob: a2f21a91d1e4bb1779c5a4cd365b0e1221850638 [file] [log] [blame]
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A representation for instrumentation options, along with operations."""
def _is_string_list(value):
if type(value) != type([]):
return False
if any([type(element) != type("") for element in value]):
return False
return True
def _make_opts(
copts = [],
conlyopts = [],
cxxopts = [],
linkopts = []):
"""Creates new instrumentation options.
The struct fields mirror the argument names of this function.
Args:
copts: A list of C/C++ compilation options passed as `--copt`
configuration flags.
conlyopts: A list of C-only compilation options passed as `--conlyopt`
configuration flags.
cxxopts: A list of C++-only compilation options passed as `--cxxopts`
configuration flags.
linkopts: A list of linker options to pass as `--linkopt`
configuration flags.
Returns:
A struct with the given instrumentation options.
"""
if not _is_string_list(copts):
fail("copts should be a list of strings")
if not _is_string_list(conlyopts):
fail("conlyopts should be a list of strings")
if not _is_string_list(cxxopts):
fail("cxxopts should be a list of strings")
if not _is_string_list(linkopts):
fail("linkopts should be a list of strings")
return struct(
copts = copts,
conlyopts = conlyopts,
cxxopts = cxxopts,
linkopts = linkopts,
)
def _merge_opts(left_opts, right_opts):
return _make_opts(
copts = left_opts.copts + right_opts.copts,
conlyopts = left_opts.conlyopts + right_opts.conlyopts,
cxxopts = left_opts.cxxopts + right_opts.cxxopts,
linkopts = left_opts.linkopts + right_opts.linkopts,
)
instrum_opts = struct(
make = _make_opts,
merge = _merge_opts,
)
instrum_defaults = struct(
# Instrumentation applied to all fuzz test executables when built in fuzzing
# mode. This mode is controlled by the `//fuzzing:cc_fuzzing_build_mode`
# config flag.
fuzzing_build = _make_opts(
copts = ["-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"],
),
libfuzzer = _make_opts(
copts = ["-fsanitize=fuzzer-no-link"],
),
# Jazzer is based on libFuzzer and hence generally requires the same
# instrumentation for native code. Since it does not support
# LeakSanitizer, the corresponding instrumentation can be disabled.
jazzer = _make_opts(
copts = [
"-fsanitize=fuzzer-no-link",
"-fno-sanitize=leak",
],
),
# Reflects the set of options at
# https://github.com/google/honggfuzz/blob/master/hfuzz_cc/hfuzz-cc.c
honggfuzz = _make_opts(
copts = [
"-mllvm",
"-inline-threshold=2000",
"-fno-builtin",
"-fno-omit-frame-pointer",
"-D__NO_STRING_INLINES",
"-fsanitize-coverage=trace-pc-guard,trace-cmp,trace-div,indirect-calls",
"-fno-sanitize=fuzzer",
],
linkopts = [
"-fno-sanitize=fuzzer",
],
),
asan = _make_opts(
copts = ["-fsanitize=address"],
linkopts = ["-fsanitize=address"],
),
msan = _make_opts(
copts = ["-fsanitize=memory"],
linkopts = ["-fsanitize=memory"],
),
msan_origin_tracking = _make_opts(
copts = [
"-fsanitize=memory",
"-fsanitize-memory-track-origins=2",
],
linkopts = ["-fsanitize=memory"],
),
ubsan = _make_opts(
copts = [
"-fsanitize=undefined",
# Enable most of the checks enabled in OSS-Fuzz:
# https://github.com/google/oss-fuzz/blob/a896ee749769bd236299041461784f483649fe80/infra/base-images/base-builder/Dockerfile#L77
# The only exception is unsigned-integer-overflow, which is not UB,
# but enabled in OSS-Fuzz in silent mode as an additional coverage
# signal. We do not do this here as it would introduce additional
# complexity (setting UBSAN_OPTIONS) to the local mode.
"-fsanitize=array-bounds,bool,builtin,enum,float-divide-by-zero,function,integer-divide-by-zero,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound,vptr",
"-fno-sanitize-recover=all",
],
linkopts = [
"-fsanitize=undefined",
# Bazel uses clang, not clang++, as the linker, which does not link
# the C++ UBSan runtime library by default, but can be instructed to
# do so with a flag.
# https://github.com/bazelbuild/bazel/issues/11122#issuecomment-896613570
"-fsanitize-link-c++-runtime",
],
),
)