# Copyright 2014 The Chromium 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/sanitizers/sanitizers.gni") # Contains the dependencies needed for sanitizers to link into executables and # shared_libraries. Unconditionally depend upon this target as it is empty if # |is_asan|, |is_lsan|, |is_tsan|, |is_msan| and |use_custom_libcxx| are false. group("deps") { if (using_sanitizer) { public_configs = [ ":sanitizer_options_link_helper" ] deps = [ ":options_sources", ] if (use_prebuilt_instrumented_libraries) { deps += [ "//third_party/instrumented_libraries:deps" ] } if (use_custom_libcxx) { deps += [ "//buildtools/third_party/libc++:libcxx_proxy" ] } } } config("sanitizer_options_link_helper") { ldflags = [ "-Wl,-u_sanitizer_options_link_helper" ] if (is_asan) { ldflags += [ "-fsanitize=address" ] } if (is_lsan) { ldflags += [ "-fsanitize=leak" ] } if (is_tsan) { ldflags += [ "-fsanitize=thread" ] } if (is_msan) { ldflags += [ "-fsanitize=memory" ] } if (is_ubsan) { ldflags += [ "-fsanitize=undefined" ] } if (is_ubsan_vptr) { ldflags += [ "-fsanitize=vptr" ] } } source_set("options_sources") { visibility = [ ":deps", "//:gn_visibility", ] sources = [ "//build/sanitizers/sanitizer_options.cc", ] # Don't compile this target with any sanitizer code. It can be called from # the sanitizer runtimes, so instrumenting these functions could cause # recursive calls into the runtime if there is an error. configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ] configs -= [ "//build/config/sanitizers:default_sanitizer_coverage_flags" ] if (is_asan) { sources += [ "//build/sanitizers/asan_suppressions.cc" ] } if (is_lsan) { sources += [ "//build/sanitizers/lsan_suppressions.cc" ] } if (is_tsan) { sources += [ "//build/sanitizers/tsan_suppressions.cc" ] } } # This config is applied by default to all targets. It sets the compiler flags # for sanitizer usage, or, if no sanitizer is set, does nothing. # # This needs to be in a separate config so that targets can opt out of # sanitizers if they desire. config("default_sanitizer_flags") { cflags = [] cflags_cc = [] ldflags = [] defines = [] # Only works on Posix-like platforms. # FIXME: this is not true, remove the conditional. if (is_posix) { # Common options for AddressSanitizer, LeakSanitizer, ThreadSanitizer, # MemorySanitizer and non-official CFI builds. if (using_sanitizer || (is_cfi && !is_official_build)) { cflags += [ "-fno-omit-frame-pointer", "-gline-tables-only", ] } if (is_asan) { asan_blacklist_path = rebase_path("//tools/memory/asan/blacklist.txt", root_build_dir) cflags += [ "-fsanitize=address", "-fsanitize-blacklist=$asan_blacklist_path", ] if (is_mac) { cflags += [ "-mllvm -asan-globals=0" ] # http://crbug.com/352073 # TODO(GYP): deal with mac_bundles. } } if (is_lsan) { cflags += [ "-fsanitize=leak" ] } if (is_tsan) { tsan_blacklist_path = rebase_path("//tools/memory/tsan_v2/ignores.txt", root_build_dir) cflags += [ "-fsanitize=thread", "-fsanitize-blacklist=$tsan_blacklist_path", ] } if (is_msan) { msan_blacklist_path = rebase_path("//tools/msan/blacklist.txt", root_build_dir) cflags += [ "-fsanitize=memory", "-fsanitize-memory-track-origins=$msan_track_origins", "-fsanitize-blacklist=$msan_blacklist_path", ] } if (is_ubsan) { ubsan_blacklist_path = rebase_path("//tools/ubsan/blacklist.txt", root_build_dir) cflags += [ # Yasm dies with an "Illegal instruction" error when bounds checking is # enabled. See http://crbug.com/489901 # "-fsanitize=bounds", "-fsanitize=float-divide-by-zero", "-fsanitize=integer-divide-by-zero", "-fsanitize=null", "-fsanitize=object-size", "-fsanitize=return", "-fsanitize=returns-nonnull-attribute", "-fsanitize=shift-exponent", "-fsanitize=signed-integer-overflow", "-fsanitize=unreachable", "-fsanitize=vla-bound", "-fsanitize-blacklist=$ubsan_blacklist_path", # Employ the experimental PBQP register allocator to avoid slow # compilation on files with too many basic blocks. # See http://crbug.com/426271. "-mllvm", "-regalloc=pbqp", # Speculatively use coalescing to slightly improve the code generated # by PBQP regallocator. May increase compile time. "-mllvm", "-pbqp-coalescing", ] } if (is_ubsan_vptr) { ubsan_vptr_blacklist_path = rebase_path("//tools/ubsan/vptr_blacklist.txt", root_build_dir) cflags += [ "-fsanitize=vptr", "-fsanitize-blacklist=$ubsan_vptr_blacklist_path", ] } if (is_cfi && !is_nacl) { cfi_blacklist_path = rebase_path("//tools/cfi/blacklist.txt", root_build_dir) cflags += [ "-flto", "-fsanitize=cfi-vcall", "-fsanitize=cfi-derived-cast", "-fsanitize=cfi-unrelated-cast", "-fsanitize-blacklist=$cfi_blacklist_path", ] ldflags += [ "-flto", "-fsanitize=cfi-vcall", "-fsanitize=cfi-derived-cast", "-fsanitize=cfi-unrelated-cast", ] # Apply a lower LTO optimization level as the default is too slow. if (is_linux) { ldflags += [ "-Wl,-plugin-opt,O1" ] } else if (is_mac) { ldflags += [ "-Wl,-mllvm,-O1" ] } # Work-around for http://openradar.appspot.com/20356002 if (is_mac) { ldflags += [ "-Wl,-all_load" ] } # Without this flag, LTO produces a .text section that is larger # than the maximum call displacement, preventing the linker from # relocating calls (http://llvm.org/PR22999). if (current_cpu == "arm") { ldflags += [ "-Wl,-plugin-opt,-function-sections" ] } if (use_cfi_diag) { cflags += [ "-fno-sanitize-trap=cfi", "-fsanitize-recover=cfi", ] ldflags += [ "-fno-sanitize-trap=cfi", "-fsanitize-recover=cfi", ] } else { defines += [ "CFI_ENFORCEMENT" ] } } if (use_custom_libcxx) { cflags_cc += [ "-nostdinc++" ] include_dirs = [ "//buildtools/third_party/libc++/trunk/include", "//buildtools/third_party/libc++abi/trunk/include", ] } } } config("default_sanitizer_coverage_flags") { cflags = [] if (use_sanitizer_coverage) { # FIXME: make this configurable. cflags += [ "-fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp" ] } }