OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 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 |
| 5 import("//build/config/chrome_build.gni") |
| 6 import("//build/config/chromecast_build.gni") |
| 7 import("//build/config/sanitizers/sanitizers.gni") |
| 8 import("//build/toolchain/toolchain.gni") |
| 9 |
| 10 # Contains the dependencies needed for sanitizers to link into executables and |
| 11 # shared_libraries. Unconditionally depend upon this target as it is empty if |
| 12 # |is_asan|, |is_lsan|, |is_tsan|, |is_msan| and |use_custom_libcxx| are false. |
| 13 group("deps") { |
| 14 public_deps = [ |
| 15 ":deps_no_options", |
| 16 ] |
| 17 if (using_sanitizer) { |
| 18 public_configs = [ |
| 19 ":sanitizer_options_link_helper", |
| 20 |
| 21 # Even when a target removes default_sanitizer_flags, it may be depending |
| 22 # on a library that did not remove default_sanitizer_flags. Thus, we need |
| 23 # to add the ldflags here as well as in default_sanitizer_flags. |
| 24 ":default_sanitizer_ldflags", |
| 25 ] |
| 26 deps = [ |
| 27 ":options_sources", |
| 28 ] |
| 29 } |
| 30 } |
| 31 |
| 32 group("deps_no_options") { |
| 33 if (using_sanitizer) { |
| 34 public_configs = [ |
| 35 # Even when a target removes default_sanitizer_flags, it may be depending |
| 36 # on a library that did not remove default_sanitizer_flags. Thus, we need |
| 37 # to add the ldflags here as well as in default_sanitizer_flags. |
| 38 ":default_sanitizer_ldflags", |
| 39 ] |
| 40 deps = [] |
| 41 if (use_prebuilt_instrumented_libraries) { |
| 42 deps += [ "//third_party/instrumented_libraries:deps" ] |
| 43 } |
| 44 if (use_custom_libcxx) { |
| 45 public_deps = [ |
| 46 "//buildtools/third_party/libc++:libcxx_proxy", |
| 47 ] |
| 48 } |
| 49 if (is_mac) { |
| 50 data_deps = [ |
| 51 ":copy_asan_runtime", |
| 52 ] |
| 53 } |
| 54 } |
| 55 } |
| 56 |
| 57 if (is_mac) { |
| 58 copy("copy_asan_runtime") { |
| 59 sources = [ |
| 60 "//third_party/llvm-build/Release+Asserts/lib/clang/$clang_version/lib/dar
win/libclang_rt.asan_osx_dynamic.dylib", |
| 61 ] |
| 62 outputs = [ |
| 63 "$root_out_dir/{{source_file_part}}", |
| 64 ] |
| 65 } |
| 66 } |
| 67 |
| 68 config("sanitizer_options_link_helper") { |
| 69 if (is_mac) { |
| 70 ldflags = [ "-Wl,-U,_sanitizer_options_link_helper" ] |
| 71 } else if (!is_win) { |
| 72 ldflags = [ "-Wl,-u_sanitizer_options_link_helper" ] |
| 73 } |
| 74 } |
| 75 |
| 76 static_library("options_sources") { |
| 77 # This is a static_library instead of a source_set, as it shouldn't be |
| 78 # unconditionally linked into targets. |
| 79 visibility = [ |
| 80 ":deps", |
| 81 "//:gn_visibility", |
| 82 ] |
| 83 sources = [ |
| 84 "//build/sanitizers/sanitizer_options.cc", |
| 85 ] |
| 86 |
| 87 # Don't compile this target with any sanitizer code. It can be called from |
| 88 # the sanitizer runtimes, so instrumenting these functions could cause |
| 89 # recursive calls into the runtime if there is an error. |
| 90 configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ] |
| 91 |
| 92 if (is_asan) { |
| 93 sources += [ "//build/sanitizers/asan_suppressions.cc" ] |
| 94 } |
| 95 |
| 96 if (is_lsan) { |
| 97 sources += [ "//build/sanitizers/lsan_suppressions.cc" ] |
| 98 } |
| 99 |
| 100 if (is_tsan) { |
| 101 sources += [ "//build/sanitizers/tsan_suppressions.cc" ] |
| 102 } |
| 103 } |
| 104 |
| 105 # Applies linker flags necessary when either :deps or :default_sanitizer_flags |
| 106 # are used. |
| 107 config("default_sanitizer_ldflags") { |
| 108 visibility = [ |
| 109 ":default_sanitizer_flags", |
| 110 ":deps", |
| 111 ] |
| 112 |
| 113 if (is_posix) { |
| 114 ldflags = [] |
| 115 if (is_asan) { |
| 116 ldflags += [ "-fsanitize=address" ] |
| 117 } |
| 118 if (is_lsan) { |
| 119 ldflags += [ "-fsanitize=leak" ] |
| 120 } |
| 121 if (is_tsan) { |
| 122 ldflags += [ "-fsanitize=thread" ] |
| 123 } |
| 124 if (is_msan) { |
| 125 ldflags += [ "-fsanitize=memory" ] |
| 126 } |
| 127 if (is_ubsan || is_ubsan_security) { |
| 128 ldflags += [ "-fsanitize=undefined" ] |
| 129 } |
| 130 if (is_ubsan_vptr) { |
| 131 ldflags += [ "-fsanitize=vptr" ] |
| 132 } |
| 133 |
| 134 if (is_cfi && !is_nacl) { |
| 135 ldflags += [ |
| 136 "-fsanitize=cfi-vcall", |
| 137 "-fsanitize=cfi-derived-cast", |
| 138 "-fsanitize=cfi-unrelated-cast", |
| 139 ] |
| 140 if (use_cfi_diag) { |
| 141 ldflags += [ |
| 142 "-fno-sanitize-trap=cfi", |
| 143 "-fsanitize-recover=cfi", |
| 144 ] |
| 145 } |
| 146 } |
| 147 } |
| 148 } |
| 149 |
| 150 config("common_sanitizer_flags") { |
| 151 cflags = [] |
| 152 cflags_cc = [] |
| 153 |
| 154 # Sanitizers need line table info for stack traces. They don't need type info |
| 155 # or variable info, so we can leave that out to speed up the build. |
| 156 if (using_sanitizer) { |
| 157 assert(is_clang, "sanitizers only supported with clang") |
| 158 cflags += [ "-gline-tables-only" ] |
| 159 } |
| 160 |
| 161 # Common options for AddressSanitizer, LeakSanitizer, ThreadSanitizer, |
| 162 # MemorySanitizer and non-official CFI builds. |
| 163 if (using_sanitizer || (is_cfi && !is_official_build)) { |
| 164 if (is_posix) { |
| 165 cflags += [ "-fno-omit-frame-pointer" ] |
| 166 } else { |
| 167 cflags += [ "/Oy-" ] |
| 168 } |
| 169 } |
| 170 |
| 171 if (use_custom_libcxx) { |
| 172 prefix = "//buildtools/third_party" |
| 173 include = "trunk/include" |
| 174 cflags_cc += [ |
| 175 "-nostdinc++", |
| 176 "-isystem" + rebase_path("$prefix/libc++/$include", root_build_dir), |
| 177 "-isystem" + rebase_path("$prefix/libc++abi/$include", root_build_dir), |
| 178 ] |
| 179 } |
| 180 } |
| 181 |
| 182 config("asan_flags") { |
| 183 cflags = [] |
| 184 if (is_asan) { |
| 185 cflags += [ "-fsanitize=address" ] |
| 186 if (is_win) { |
| 187 cflags += [ "-fsanitize-blacklist=" + |
| 188 rebase_path("//tools/memory/asan/blacklist_win.txt", |
| 189 root_build_dir) ] |
| 190 } else { |
| 191 # TODO(rnk): Remove this as discussed in http://crbug.com/427202. |
| 192 cflags += |
| 193 [ "-fsanitize-blacklist=" + |
| 194 rebase_path("//tools/memory/asan/blacklist.txt", root_build_dir) ] |
| 195 } |
| 196 if (is_android) { |
| 197 # Android build relies on -Wl,--gc-sections removing unreachable code. |
| 198 # ASan instrumentation for globals inhibits this and results in a |
| 199 # library with unresolvable relocations. |
| 200 # TODO(eugenis): find a way to reenable this. |
| 201 cflags += [ |
| 202 "-mllvm", |
| 203 "-asan-globals=0", |
| 204 ] |
| 205 } else if (is_mac) { |
| 206 # http://crbug.com/352073 |
| 207 cflags += [ |
| 208 "-mllvm", |
| 209 "-asan-globals=0", |
| 210 ] |
| 211 # TODO(GYP): deal with mac_bundles. |
| 212 } else if (is_win) { |
| 213 assert(target_cpu == "x86", "WinASan is 32-bit only currently") |
| 214 if (is_component_build) { |
| 215 libs = [ |
| 216 "clang_rt.asan_dynamic-i386.lib", |
| 217 "clang_rt.asan_dynamic_runtime_thunk-i386.lib", |
| 218 ] |
| 219 } else { |
| 220 # TODO(rnk): DLLs in the non-component build should link against |
| 221 # clang_rt.asan_dll_thunk-i386.lib instead. |
| 222 libs = [ "clang_rt.asan-i386.lib" ] |
| 223 } |
| 224 } |
| 225 } |
| 226 } |
| 227 |
| 228 config("cfi_flags") { |
| 229 cflags = [] |
| 230 if (is_cfi && !is_nacl) { |
| 231 cfi_blacklist_path = |
| 232 rebase_path("//tools/cfi/blacklist.txt", root_build_dir) |
| 233 cflags += [ |
| 234 "-fsanitize=cfi-vcall", |
| 235 "-fsanitize=cfi-derived-cast", |
| 236 "-fsanitize=cfi-unrelated-cast", |
| 237 "-fsanitize-blacklist=$cfi_blacklist_path", |
| 238 ] |
| 239 |
| 240 if (use_cfi_diag) { |
| 241 cflags += [ |
| 242 "-fno-sanitize-trap=cfi", |
| 243 "-fsanitize-recover=cfi", |
| 244 "-fno-inline-functions", |
| 245 "-fno-inline", |
| 246 "-fno-omit-frame-pointer", |
| 247 "-O1", |
| 248 ] |
| 249 } else { |
| 250 defines = [ "CFI_ENFORCEMENT" ] |
| 251 } |
| 252 } |
| 253 } |
| 254 |
| 255 config("coverage_flags") { |
| 256 cflags = [] |
| 257 |
| 258 if (use_sanitizer_coverage) { |
| 259 cflags += [ |
| 260 "-fsanitize-coverage=$sanitizer_coverage_flags", |
| 261 "-mllvm", |
| 262 "-sanitizer-coverage-prune-blocks=1", |
| 263 ] |
| 264 if (target_cpu == "arm") { |
| 265 # http://crbug.com/517105 |
| 266 cflags += [ |
| 267 "-mllvm", |
| 268 "-sanitizer-coverage-block-threshold=0", |
| 269 ] |
| 270 } |
| 271 defines = [ "SANITIZER_COVERAGE" ] |
| 272 } |
| 273 } |
| 274 |
| 275 config("lsan_flags") { |
| 276 if (is_lsan) { |
| 277 cflags = [ "-fsanitize=leak" ] |
| 278 } |
| 279 } |
| 280 |
| 281 config("msan_flags") { |
| 282 if (is_msan) { |
| 283 assert(is_linux, "msan only supported on linux x86_64") |
| 284 msan_blacklist_path = |
| 285 rebase_path("//tools/msan/blacklist.txt", root_build_dir) |
| 286 cflags = [ |
| 287 "-fsanitize=memory", |
| 288 "-fsanitize-memory-track-origins=$msan_track_origins", |
| 289 "-fsanitize-blacklist=$msan_blacklist_path", |
| 290 ] |
| 291 } |
| 292 } |
| 293 |
| 294 config("tsan_flags") { |
| 295 if (is_tsan) { |
| 296 assert(is_linux, "tsan only supported on linux x86_64") |
| 297 tsan_blacklist_path = |
| 298 rebase_path("//tools/memory/tsan_v2/ignores.txt", root_build_dir) |
| 299 cflags = [ |
| 300 "-fsanitize=thread", |
| 301 "-fsanitize-blacklist=$tsan_blacklist_path", |
| 302 ] |
| 303 } |
| 304 } |
| 305 |
| 306 config("ubsan_flags") { |
| 307 cflags = [] |
| 308 if (is_ubsan) { |
| 309 ubsan_blacklist_path = |
| 310 rebase_path("//tools/ubsan/blacklist.txt", root_build_dir) |
| 311 cflags += [ |
| 312 # Yasm dies with an "Illegal instruction" error when bounds checking is |
| 313 # enabled. See http://crbug.com/489901 |
| 314 # "-fsanitize=bounds", |
| 315 "-fsanitize=float-divide-by-zero", |
| 316 "-fsanitize=integer-divide-by-zero", |
| 317 "-fsanitize=null", |
| 318 "-fsanitize=object-size", |
| 319 "-fsanitize=return", |
| 320 "-fsanitize=returns-nonnull-attribute", |
| 321 "-fsanitize=shift-exponent", |
| 322 "-fsanitize=signed-integer-overflow", |
| 323 "-fsanitize=unreachable", |
| 324 "-fsanitize=vla-bound", |
| 325 "-fsanitize-blacklist=$ubsan_blacklist_path", |
| 326 ] |
| 327 |
| 328 # Chromecast ubsan builds fail to compile with these |
| 329 # experimental flags, so only add them to non-chromecast ubsan builds. |
| 330 if (!is_chromecast) { |
| 331 cflags += [ |
| 332 # Employ the experimental PBQP register allocator to avoid slow |
| 333 # compilation on files with too many basic blocks. |
| 334 # See http://crbug.com/426271. |
| 335 "-mllvm", |
| 336 "-regalloc=pbqp", |
| 337 |
| 338 # Speculatively use coalescing to slightly improve the code generated |
| 339 # by PBQP regallocator. May increase compile time. |
| 340 "-mllvm", |
| 341 "-pbqp-coalescing", |
| 342 ] |
| 343 } |
| 344 } |
| 345 } |
| 346 |
| 347 config("ubsan_no_recover") { |
| 348 if (is_ubsan_no_recover) { |
| 349 cflags = [ "-fno-sanitize-recover=undefined" ] |
| 350 } |
| 351 } |
| 352 |
| 353 config("ubsan_security_flags") { |
| 354 if (is_ubsan_security) { |
| 355 ubsan_blacklist_path = |
| 356 rebase_path("//tools/ubsan/blacklist.txt", root_build_dir) |
| 357 cflags = [ |
| 358 "-fsanitize=signed-integer-overflow,shift", |
| 359 "-fsanitize-blacklist=$ubsan_blacklist_path", |
| 360 ] |
| 361 } |
| 362 } |
| 363 |
| 364 config("ubsan_vptr_flags") { |
| 365 if (is_ubsan_vptr) { |
| 366 ubsan_vptr_blacklist_path = |
| 367 rebase_path("//tools/ubsan/vptr_blacklist.txt", root_build_dir) |
| 368 cflags = [ |
| 369 "-fsanitize=vptr", |
| 370 "-fsanitize-blacklist=$ubsan_vptr_blacklist_path", |
| 371 ] |
| 372 } |
| 373 } |
| 374 |
| 375 all_sanitizer_configs = [ |
| 376 ":common_sanitizer_flags", |
| 377 ":coverage_flags", |
| 378 ":default_sanitizer_ldflags", |
| 379 ":asan_flags", |
| 380 ":cfi_flags", |
| 381 ":lsan_flags", |
| 382 ":msan_flags", |
| 383 ":tsan_flags", |
| 384 ":ubsan_flags", |
| 385 ":ubsan_no_recover", |
| 386 ":ubsan_security_flags", |
| 387 ":ubsan_vptr_flags", |
| 388 ] |
| 389 |
| 390 # This config is applied by default to all targets. It sets the compiler flags |
| 391 # for sanitizer usage, or, if no sanitizer is set, does nothing. |
| 392 # |
| 393 # This needs to be in a separate config so that targets can opt out of |
| 394 # sanitizers (by removing the config) if they desire. Even if a target |
| 395 # removes this config, executables & shared libraries should still depend on |
| 396 # :deps if any of their dependencies have not opted out of sanitizers. |
| 397 # Keep this list in sync with default_sanitizer_flags_but_ubsan_vptr. |
| 398 config("default_sanitizer_flags") { |
| 399 configs = all_sanitizer_configs |
| 400 } |
| 401 |
| 402 # This config is equivalent to default_sanitizer_flags, but excludes ubsan_vptr. |
| 403 # This allows to selectively disable ubsan_vptr, when needed. In particular, |
| 404 # if some third_party code is required to be compiled without rtti, which |
| 405 # is a requirement for ubsan_vptr. |
| 406 config("default_sanitizer_flags_but_ubsan_vptr") { |
| 407 configs = all_sanitizer_configs - [ ":ubsan_vptr_flags" ] |
| 408 } |
| 409 |
| 410 config("default_sanitizer_flags_but_coverage") { |
| 411 configs = all_sanitizer_configs - [ ":coverage_flags" ] |
| 412 } |
OLD | NEW |