| # 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" ] |
| } |