Add ASAN, TSAN, UBSAN support

TBR=machenbach@chromium.org

Bug: v8:8772
Change-Id: Ie1cecfa618937031cf86ee9904847141d99f358d
Reviewed-on: https://chromium-review.googlesource.com/c/1472756
Reviewed-by: Yang Guo <yangguo@chromium.org>
diff --git a/Makefile b/Makefile
index ab6a634..694efec 100644
--- a/Makefile
+++ b/Makefile
@@ -16,19 +16,19 @@
 
 # Generate GN configs
 out/Release:
-	gn gen $@ -q --args="is_debug = false"
+	tools/gn-gen.py out/Release
 
 out/Debug:
-	gn gen $@ -q --args="is_debug = true v8_optimized_debug = true"
+	tools/gn-gen.py out/Debug --debug
 
 # Build
 .PHONY: build.Release
 build.Release: out/Release
-	gn gen $< && autoninja -C $<
+	autoninja -C $<
 
 .PHONY:
 build.Debug: out/Debug
-	gn gen $< && autoninja -C $<
+	autoninja -C $<
 
 # Link node binary
 node: build.Release
diff --git a/tools/generate_config_gypi.py b/tools/generate_config_gypi.py
index 727d94e..7f6b859 100644
--- a/tools/generate_config_gypi.py
+++ b/tools/generate_config_gypi.py
@@ -32,6 +32,7 @@
           "Debug" if config["is_debug"] == "true" else "Release",
     },
     "variables": {
+      "asan": bool_string_to_number(config["is_asan"]),
       "node_module_version": string_to_number(config["node_module_version"]),
       "node_report": config["node_report"],
       "node_shared": bool_string_to_number(config["is_component_build"]),
diff --git a/tools/gn-gen.py b/tools/gn-gen.py
new file mode 100755
index 0000000..e317931
--- /dev/null
+++ b/tools/gn-gen.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# Copyright 2019 the V8 project 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 argparse
+import os
+import subprocess
+import sys
+
+def ToBool(option):
+  return "true" if option else "false"
+
+def GenerateBuildFiles(options):
+  gn_args = []
+  gn_args.append("is_debug=%s" % ToBool(options.debug))
+  gn_args.append("use_goma=%s" % ToBool(options.goma))
+  gn_args.append("is_component_build=%s" % ToBool(options.shared))
+  if options.sysroot:
+    gn_args.append("use_sysroot=true")
+    gn_args.append("use_custom_libcxx=true")
+  if options.asan:
+    gn_args.append("is_lsan=true")
+    gn_args.append("is_asan=true")
+    gn_args.append("v8_enable_test_features=true")
+  if options.tsan:
+    gn_args.append("is_tsan=true")
+    gn_args.append("v8_enable_test_features=true")
+  if options.ubsan:
+    gn_args.append("is_ubsan=true")
+    gn_args.append("is_ubsan_no_recover=true")
+    gn_args.append("v8_enable_test_features=true")
+
+  flattened_args = ' '.join(gn_args)
+  args = ["gn", "gen", options.out_dir, "-q", "--args=" + flattened_args]
+  print('\n'.join(gn_args))
+  subprocess.check_call(args)
+
+def ParseOptions(args):
+  parser = argparse.ArgumentParser(
+      description="Generate GN build configurations")
+  parser.add_argument("out_dir", help="Build directory")
+  parser.add_argument("--goma", help="Use goma", action="store_true")
+  parser.add_argument("--asan", help="Use address sanitizer",
+                      action="store_true", default=False)
+  parser.add_argument("--tsan", help="Use thread sanitizer",
+                      action="store_true", default=False)
+  parser.add_argument("--ubsan", help="Use undefined-behavior sanitizer",
+                      action="store_true", default=False)
+  parser.add_argument("--shared", help="Use component build",
+                      action="store_true", default=False)
+  parser.add_argument("--sysroot", help="Use bundled sysroot",
+                      action="store_true", default=False)
+  parser.add_argument("--debug", help="Debug mode",
+                      action="store_true", default=False)
+  options = parser.parse_args(args)
+
+  # Only one sanitizer is enabled.
+  assert(options.asan + options.tsan + options.ubsan <= 1)
+  if options.asan or options.tsan or options.ubsan:
+    options.shared = False
+    options.debug = False
+  return options
+
+if __name__ == "__main__":
+  options = ParseOptions(sys.argv[1:])
+  GenerateBuildFiles(options)
diff --git a/tools/memory/asan/blacklist.txt b/tools/memory/asan/blacklist.txt
new file mode 100644
index 0000000..2bb1aa9
--- /dev/null
+++ b/tools/memory/asan/blacklist.txt
@@ -0,0 +1,4 @@
+# The rules in this file are only applied at compile time. If you can modify the
+# source in question, consider function attributes to disable instrumentation.
+#
+# Please think twice before you add or remove these rules.
\ No newline at end of file
diff --git a/tools/memory/tsan_v2/ignores.txt b/tools/memory/tsan_v2/ignores.txt
new file mode 100644
index 0000000..80babf4
--- /dev/null
+++ b/tools/memory/tsan_v2/ignores.txt
@@ -0,0 +1,5 @@
+# The rules in this file are only applied at compile time. If you can modify the
+# source in question, consider function attributes to disable instrumentation.
+#
+# Please think twice before you add or remove these rules.
+# Data races should typically go to suppressions.txt.
\ No newline at end of file
diff --git a/tools/ubsan/blacklist.txt b/tools/ubsan/blacklist.txt
new file mode 100644
index 0000000..8be46d0
--- /dev/null
+++ b/tools/ubsan/blacklist.txt
@@ -0,0 +1,15 @@
+#############################################################################
+# UBSan blacklist.
+
+# UBSan bug, fixed in LLVM r350779. Drop this suppression when that
+# revision has rolled into Chromium's bundled Clang.
+fun:*v8*internal*NewArray*
+
+# Bug 8735: PropertyCallbackInfo<void> vs PropertyCallbackInfo<T>.
+fun:*v8*internal*PropertyCallbackArguments*CallAccessorSetter*
+fun:*v8*internal*PropertyCallbackArguments*BasicCallNamedGetterCallback*
+fun:*v8*internal*InvokeAccessorGetterCallback*
+
+# Bug 8735: WeakCallbackInfo<void> vs. WeakCallbackInfo<T>.
+fun:*v8*internal*GlobalHandles*PendingPhantomCallback*Invoke*
+fun:*v8*internal*GlobalHandles*Node*PostGarbageCollectionProcessing*