blob: 61606ac5c717cd4cc2eced549baf200bc4375d1b [file] [log] [blame]
# Copyright 2017 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/config/clang/clang.gni")
import("//build/toolchain/variant.gni")
declare_args() {
# Default [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
# options (before the `ASAN_OPTIONS` environment variable is read at
# runtime). This can be set as a build argument to affect most "asan"
# variants in `known_variants` (which see), or overridden in
# toolchain_args in one of those variants. Note that setting this
# nonempty may conflict with programs that define their own
# `__asan_default_options` C function.
asan_default_options = ""
if (is_fuchsia) {
# TODO(45047): Temporary until all lsan bugs are filed and marked with
# deps += [ "//build/config/sanitizers:suppress-lsan.DO-NOT-USE-THIS" ]
asan_default_options = "detect_leaks=0"
}
# Default [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
# options (before the `UBSAN_OPTIONS` environment variable is read at
# runtime). This can be set as a build argument to affect most "ubsan"
# variants in `known_variants` (which see), or overridden in
# toolchain_args in one of those variants. Note that setting this
# nonempty may conflict with programs that define their own
# `__ubsan_default_options` C function.
ubsan_default_options = "print_stacktrace=1:halt_on_error=1"
}
# TODO(45047): Temporary while leaks are plugged.
# As leak bugs are found, file a bug #nnnnn for the leaky test/component,
# and then add:
# ```
# # TODO(nnnnn): Fix the leaks and remove this.
# deps += [ "//build/config/sanitizers:suppress-lsan.DO-NOT-USE-THIS" ]
# ```
# to the target that builds the leaky code. When all leaky tests have been
# marked that way, the asan_default_options default above will be removed.
source_set("suppress-lsan.DO-NOT-USE-THIS") {
# This would conflict with the generic one.
if (asan_default_options == "") {
sources = [ "asan_default_options.c" ]
defines = [ "ASAN_DEFAULT_OPTIONS=\"detect_leaks=0\"" ]
configs -= [ "//build/config:symbol_visibility_hidden" ]
cflags = [ "-fPIE" ]
# TODO(45130): See below.
public_configs = [ ":rust-suppress-lsan.DO-NOT-USE-THIS" ]
}
}
# TODO(45130): See below.
config("rust-suppress-lsan.DO-NOT-USE-THIS") {
visibility = [ ":suppress-lsan.DO-NOT-USE-THIS" ]
rustflags = [ "-Clink-arg=" + rebase_path(
"$target_out_dir/suppress-lsan.DO-NOT-USE-THIS.asan_default_options.c.o",
root_build_dir) ]
}
variant("asan") {
common_flags = [ "-fsanitize=address" ]
# TODO(phosek): use runtime.json instead of invoking Clang.
if (is_fuchsia) {
extension = ".so"
} else if (is_linux) {
extension = ".a"
} else if (is_mac) {
extension = "_osx_dynamic.dylib"
} else {
extension = ".a"
}
libclang_rt_asan =
exec_script("/usr/bin/env",
[
"${clang_prefix}/clang",
"--target=${clang_target}",
"-print-file-name=libclang_rt.asan${extension}",
],
"trim string")
rustflags = [ "-Clink-arg=${libclang_rt_asan}" ]
if (is_fuchsia) {
rustflags += [ "-Clink-arg=-dynamic-linker=asan/ld.so.1" ]
}
# ASan wants frame pointers because it captures stack traces
# on allocations and such, not just on errors.
configs = [ "//build/config:frame_pointers" ]
if (asan_default_options != "") {
deps = [ ":asan_default_options" ]
}
}
if (asan_default_options != "") {
source_set("asan_default_options") {
visibility = [ ":*" ]
sources = [ "asan_default_options.c" ]
defines = [ "ASAN_DEFAULT_OPTIONS=\"${asan_default_options}\"" ]
# On Fuchsia, the ASan runtime is dynamically linked and needs to have
# the __asan_default_options symbol exported. On systems where the
# ASan runtime is statically linked, it doesn't matter either way.
configs -= [ "//build/config:symbol_visibility_hidden" ]
# This is the default on Fuchsia but not on all host platforms.
# It's necessary to link into Rust binaries, which are PIE even
# on platforms where C binaries are not PIE by default.
cflags = [ "-fPIE" ]
# TODO(45130): Remove this when GN is improved. The link inputs from
# this source_set() are just silently ignored by an executable() target
# that uses rustc to link. So shove the link input in through the back
# door because we can't have nice things.
public_configs = [ ":rust_asan_default_options" ]
}
# TODO(45130): I just can't even.
config("rust_asan_default_options") {
visibility = [ ":asan_default_options" ]
rustflags =
[ "-Clink-arg=" + rebase_path(
"$target_out_dir/asan_default_options.asan_default_options.c.o",
root_build_dir) ]
}
}
# rustc flags for AddressSanitizer, primarily used for fuzzing Rust code.
# TODO(45102): This is technically wrong; it will use clang's ASan.
# rustc is built from a different fork of LLVM and should use a matching ASan.
# However, Fuchsia's libc and dynamic linker cooperate to set up the shadow
# memory and currently always link against clang's ASan. Using both rustc and
# clang's ASan would also be infeasible, as symbol names and shadow memory
# regions would conflict.
#
# Thus, variants using this config currently IGNORE the potential ABI
# incompatibility and simply use clang's ASan. If/when this breaks, these
# test-only variants should be disabled until a resolution can be found.
#
# Additionally, variants using this config CANNOT be used on binaries linked
# by rustc, as it will fail to find its runtime. It CAN be used to build
# libraries with rustc that are then linked into executables by clang, e.g.
# fuzzers.
variant("rust-asan") {
rustflags = [ "-Zsanitizer=address" ]
}
variant("ubsan") {
common_flags = [ "-fsanitize=undefined" ]
libprefix = toolchain_variant.name
if (libprefix == "ubsan-fuzzer") {
# Fuchsia-built fuzzers don't have their own separate libprefix.
# They just use the base variant.
libprefix = "ubsan"
}
dynamic_linker_flags = "-dynamic-linker=$libprefix/ld.so.1"
ldflags = [ "-Wl,$dynamic_linker_flags" ]
rustflags = [ "-Clink-arg=$dynamic_linker_flags" ]
if (ubsan_default_options != "") {
deps = [ ":ubsan_default_options" ]
}
}
if (ubsan_default_options != "") {
source_set("ubsan_default_options") {
visibility = [ ":*" ]
sources = [ "ubsan_default_options.c" ]
defines = [ "UBSAN_DEFAULT_OPTIONS=\"${ubsan_default_options}\"" ]
# On Fuchsia, the UBSan runtime is dynamically linked and needs to have
# the __ubsan_default_options symbol exported. On systems where the
# UBSan runtime is statically linked, it doesn't matter either way.
configs -= [ "//build/config:symbol_visibility_hidden" ]
}
}
variant("fuzzer") {
common_flags = [ "-fsanitize=fuzzer" ]
# TODO (TC-251): This shouldn't be necessary, but libzircon isn't currently
# linked into libFuzzer on Fuchsia.
if (is_fuchsia) {
libs = [ "zircon" ]
}
rustflags = [
"-Cpasses=sancov",
"-Cllvm-args=-sanitizer-coverage-level=4",
"-Cllvm-args=-sanitizer-coverage-trace-compares",
"-Cllvm-args=-sanitizer-coverage-inline-8bit-counters",
"-Cllvm-args=-sanitizer-coverage-pc-table",
]
}
variant("sancov") {
common_flags = [ "-fsanitize-coverage=trace-pc-guard" ]
}