Import changes for goma client

  - 6ba7ba97b74f27fe8971a636776fd8e4866f17e6 bug fix: opposite condition was given for gcc flags.
  - 3e1e782d86d8ee82914a45f2e7f0143ab0542157 [cleanup] moved where to enable clang modules support.
  - 7fd5eba6cbe8e92b8ff20a22b7c49927df949d37 Move compiler specific ShouldFallback code to compiler's ...
  - 80a1ddc29616db0fccb66388644210290043c32a include processor shouldn't fail if stdc-predef.h is miss...
  - e397133b6e45a924711ad3f629fe92517c3ff982 goma archive should contain LICENSE file
  - 51eed495ba6c129cdcb98475aab4b8b56c14a1b9 Revert "Reland "update win_toolchain""
  - 505b2d538d1c20de1311497528410c06c6600f77 Fix to collect chromeos clang resources
  - 7a5ca494e41e917483d901b69239bdad151d3ab7 Reland "update win_toolchain"
  - f9e64e28019f21c122b6af53ce6f5d42b872da9f Make runhooks for windows toolchain run before clang update
  - b5bf17db9114b1c00d25656aee6d6339f0a670e5 Roll client/third_party/nasm/ 313e2e8b9..ae8e4ca1c (1 com...
  - 9cb38d6d7992d3c1e219e7b80f85f10c7789f380 Move link and precompiled header to CompileFlags
  - 651c014f627ef9e7c3f429522b93ee70c03f7c01 suppress tsan failure in abseil
  - ee26c5d47d574b3c9e0637d588349cd2cc5a0de1 Roll client/third_party/breakpad/breakpad/ 54fa71efb..a0e...
  - 144e5a641538126436d9c640a0dabf5824cf1891 Record failure of updating required files.
  - cdd826eb6b7a3a9f4a6dfb6c8e4f5d53b1c2da05 Revert "update win_toolchain"
  - f6200544dfc76dc4dc026c5e056bd4846eb7f136 client: Fix HTTP status lookup in status page script
  - ec143070d399dc54a9d13a93deca84df12df350b Roll client/third_party/zlib/ 6c1421668..1337da531 (116 c...
  - 30502b42b04c153440aa217e831a1384603717c0 update buildtools
  - 76a498920050869f71c0c34b608912ba3468417e Add document for include processor
  - 618fd3e3f31f1a0c020be505a4f138e829f6f8e3 Support clang in chromeos chroot for ATS
  - 03690944ee3620d9c0d118df34b8655ff8ef1572 update win_toolchain
  - a81da25f5f772ee75769b33c37c05f6b9f25505f update excluded folder for copybara
  - ce5d54e0fb11bbfba85c95eb7bb1b9230469fa43 Use Chromium's zlib repository instead.
  - afbb53cf251c16ef3445533fb26103eedca700fc fix typo in licenses.py
  - b9a143716e9e2946f4b75c411b32f37614d76f18 remove yasm directory
  - b02c2bfd358559876348c3dc5cf96a54d8fa7bb0 Use nasm instead of yasm to build BoringSSL assembler on ...
  - b3564817cf24472a419fbd4a09de4061beb3a7f9 client: Use constexpr defs for upload file size limits
  - 1b41705b9c8005890a01547aab25ba8c39265814 http: fix IsHealthyRecently

GitOrigin-RevId: 6ba7ba97b74f27fe8971a636776fd8e4866f17e6
Change-Id: I42b30ec3f86a3bf2053dd92b71597353a86db199
diff --git a/DEPS b/DEPS
index 19c67e0..81f9e28 100644
--- a/DEPS
+++ b/DEPS
@@ -19,9 +19,9 @@
      Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' +
          '2fe3bd994b3189899d93f1d5a881e725e046fdc2',
 
-     # zlib 1.2.8
+     # zlib
      "client/third_party/zlib":
-     "https://goma.googlesource.com/zlib.git@50893291621658f355bc5b4d450a8d06a563053d",
+     "https://chromium.googlesource.com/chromium/src/third_party/zlib@1337da5314a9716c0653301cceeb835d17fd7ea4",
 
      # xz v5.2.0
      "client/third_party/xz":
@@ -42,22 +42,22 @@
      # google-breakpad
      "client/third_party/breakpad/breakpad":
      Var("chromium_git") + "/breakpad/breakpad.git@" +
-         "54fa71efbe50fb2b58096d871575b59e12edba6d",
+         "a0e078365d0515f4ffdfc3389d92b2c062f62132",
 
      # lss
      "client/third_party/lss":
      Var("chromium_git") + "/linux-syscall-support.git@" +
          "a89bf7903f3169e6bc7b8efc10a73a7571de21cf",
 
-     # chrome's patched-yasm
-     "client/third_party/yasm/source/patched-yasm":
-     Var("chromium_git") + "/chromium/deps/yasm/patched-yasm.git@" +
-         "b98114e18d8b9b84586b10d24353ab8616d4c5fc",
+     # nasm
+     "client/third_party/nasm":
+     Var("chromium_git") + "/chromium/deps/nasm.git@" +
+         "ae8e4ca1c64c861de419c93385a0fc66a39141e2",
 
      # chromium's buildtools containing libc++, libc++abi, clang_format and gn.
      "client/buildtools":
-     Var("chromium_git") + "/chromium/buildtools@" +
-         "24ebce4578745db15274e180da1938ebc1358243",
+     Var("chromium_git") + "/chromium/src/buildtools@" +
+         "6b05562fca005bb3c7131fece22cc5530938b7d8",
 
      # libFuzzer
      "client/third_party/libFuzzer/src":
@@ -95,6 +95,12 @@
 }
 
 hooks = [
+     # Update the Windows toolchain if necessary. Must run before 'clang' below.
+     {
+       'name': 'win_toolchain',
+       'pattern': '.',
+       'action': ['python', 'client/build/vs_toolchain.py', 'update'],
+     },
      {
        "name": "clang",
        "pattern": ".",
@@ -187,12 +193,6 @@
                      '-s', 'client/buildtools/linux64/clang-format.sha1',
          ],
      },
-     # Update the Windows toolchain if necessary.
-     {
-       'name': 'win_toolchain',
-       'pattern': '.',
-       'action': ['python', 'client/build/vs_toolchain.py', 'update'],
-     },
      # Update the Mac toolchain if necessary.
      {
        'name': 'mac_toolchain',
diff --git a/build/archive.py b/build/archive.py
index 944d9f3..866c381 100755
--- a/build/archive.py
+++ b/build/archive.py
@@ -244,12 +244,13 @@
       shutil.copy(pdb, distname)
     for f in ('.vpython', 'goma_auth.py', 'goma_ctl.py', 'goma_ctl.bat',
               'diagnose_goma_log.py', 'compiler_proxy.sym', 'sha256.json',
-              'gomacc.sym'):
+              'gomacc.sym', 'LICENSE'):
       shutil.copy(f, distname)
   else:
     for f in ('.vpython', 'gomacc', 'compiler_proxy', 'goma_fetch',
               'report_env.sh', 'diagnose_goma_log.py', 'compiler_proxy.sym',
-              'goma_auth.py', 'goma_ctl.py', 'sha256.json', 'gomacc.sym'):
+              'goma_auth.py', 'goma_ctl.py', 'sha256.json', 'gomacc.sym',
+              'LICENSE'):
       shutil.copy(f, distname)
     CreatePlatformGomacc(distname, options.platform)
     InstallPlatformFiles(distname, options.platform)
diff --git a/build/compiled_action.gni b/build/compiled_action.gni
index 3d520e7..48c5f84 100644
--- a/build/compiled_action.gni
+++ b/build/compiled_action.gni
@@ -1,4 +1,4 @@
-# Copied from chromium build/.
+# copied from Chromium's build/
 #
 # Copyright 2014 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
@@ -30,9 +30,9 @@
 #       of these change. If inputs is empty, the step will run only when the
 #       binary itself changes.
 #
-#   visibility
+#   depfile
 #   deps
-#   args   (all optional)
+#   visibility   (all optional)
 #       Same meaning as action/action_foreach.
 #
 #
@@ -83,19 +83,25 @@
          "compiled_action doesn't take a sources arg. Use inputs instead.")
 
   action(target_name) {
-    if (defined(invoker.visibility)) {
-      visibility = invoker.visibility
+    forward_variables_from(invoker,
+                           [
+                             "data_deps",
+                             "deps",
+                             "depfile",
+                             "inputs",
+                             "outputs",
+                             "testonly",
+                             "visibility",
+                           ])
+    if (!defined(deps)) {
+      deps = []
+    }
+    if (!defined(inputs)) {
+      inputs = []
     }
 
     script = "//build/gn_run_binary.py"
 
-    if (defined(invoker.inputs)) {
-      inputs = invoker.inputs
-    } else {
-      inputs = []
-    }
-    outputs = invoker.outputs
-
     # Constuct the host toolchain version of the tool.
     host_tool = invoker.tool + "($host_toolchain)"
 
@@ -108,15 +114,7 @@
         get_label_info(host_tool, "root_out_dir") + "/" +
         get_label_info(host_tool, "name") + _host_executable_suffix
 
-    # Add the executable itself as an input.
-    inputs += [ host_executable ]
-
-    deps = [
-      host_tool,
-    ]
-    if (defined(invoker.deps)) {
-      deps += invoker.deps
-    }
+    deps += [ host_tool ]
 
     # The script takes as arguments the binary to run, and then the arguments
     # to pass it.
@@ -131,20 +129,24 @@
   assert(defined(invoker.args), "args must be defined for $target_name")
 
   action_foreach(target_name) {
-    # Otherwise this is a standalone action, define visibility if requested.
-    if (defined(invoker.visibility)) {
-      visibility = invoker.visibility
+    forward_variables_from(invoker,
+                           [
+                             "deps",
+                             "depfile",
+                             "inputs",
+                             "outputs",
+                             "sources",
+                             "testonly",
+                             "visibility",
+                           ])
+    if (!defined(deps)) {
+      deps = []
+    }
+    if (!defined(inputs)) {
+      inputs = []
     }
 
     script = "//build/gn_run_binary.py"
-    sources = invoker.sources
-
-    if (defined(invoker.inputs)) {
-      inputs = invoker.inputs
-    } else {
-      inputs = []
-    }
-    outputs = invoker.outputs
 
     # Constuct the host toolchain version of the tool.
     host_tool = invoker.tool + "($host_toolchain)"
@@ -158,15 +160,7 @@
         get_label_info(host_tool, "root_out_dir") + "/" +
         get_label_info(host_tool, "name") + _host_executable_suffix
 
-    # Add the executable itself as an input.
-    inputs += [ host_executable ]
-
-    deps = [
-      host_tool,
-    ]
-    if (defined(invoker.deps)) {
-      deps += invoker.deps
-    }
+    deps += [ host_tool ]
 
     # The script takes as arguments the binary to run, and then the arguments
     # to pass it.
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 2898662..9362110 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -88,6 +88,7 @@
   "//build/config/compiler:compiler",
   "//build/config/compiler:default_include_dirs",
   "//build/config/compiler:goma_code",
+  "//build/config/compiler:default_optimization",
 
   # libc++/libc++abi requires a config whose name is 'chromium_code'.
   "//build/config/compiler:chromium_code",
@@ -99,10 +100,7 @@
   "//build/config/sanitizers:default_sanitizer_flags",
 ]
 if (is_debug) {
-  default_compiler_configs += [
-    "//build/config:debug",
-    "//build/config/compiler:no_optimize",
-  ]
+  default_compiler_configs += [ "//build/config:debug" ]
 
   if (os == "win" && use_incremental_link) {
     # Note: we don't make "incremental_linking" on when is_debug=false, because
@@ -111,10 +109,7 @@
     default_compiler_configs += [ "//build/config/win:incremental_linking" ]
   }
 } else {
-  default_compiler_configs += [
-    "//build/config:release",
-    "//build/config/compiler:optimize",
-  ]
+  default_compiler_configs += [ "//build/config:release" ]
 
   if (os == "win" && !use_link_time_optimization) {
     # When !is_debug && !use_link_time_optimization, /INCREMENTAL works.
@@ -188,6 +183,7 @@
     "//build/config/win:rand_s",
     "//build/config/win:sdk_link",
     "//build/config/win:console",
+    "//build/config/win:default_crt",
   ]
   default_compiler_configs += win_configs
 }
diff --git a/build/config/c++/c++.gni b/build/config/c++/c++.gni
index 60a2c72..abc08cd 100644
--- a/build/config/c++/c++.gni
+++ b/build/config/c++/c++.gni
@@ -1,3 +1,4 @@
 # libc++abi needs to be exported from executables to be picked up by shared
 # libraries on certian instrumented builds.
 export_libcxxabi_from_executables = false
+libcxx_is_shared = false
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index fa3b803..7d0fca5 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -303,6 +303,19 @@
   }
 }
 
+config("optimize_max") {
+  # This is for nasm.
+  configs = [ ":optimize" ]
+}
+
+config("default_optimization") {
+  if (is_debug) {
+    configs = [ ":no_optimize" ]
+  } else {
+    configs = [ ":optimize" ]
+  }
+}
+
 # rtti -------------------------------------------------------------------
 config("rtti") {
   if (os == "win") {
@@ -460,6 +473,14 @@
   if (is_clang) {
     cflags_cc = [ "-Wno-implicit-fallthrough" ]
   }
+
+  if (os == "win") {
+    defines = [
+      # These are for nasm.
+      "_CRT_NONSTDC_NO_WARNINGS",
+      "_CRT_SECURE_NO_WARNINGS",
+    ]
+  }
 }
 
 # Some code presumes that pointers to structures/objects are compatible
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
new file mode 100644
index 0000000..b1f5587
--- /dev/null
+++ b/build/config/compiler/compiler.gni
@@ -0,0 +1,6 @@
+# Copyright (c) 2019 Google Inc. All Rights Reserved.
+
+# TODO: move gn args to here like Chromium do.
+
+import("//build/config/sanitizers/sanitizers.gni")
+import("//build/toolchain/toolchain.gni")
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 25e5dbe..9740572 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -30,6 +30,14 @@
   ]
 }
 
+config("release_crt") {
+  # This is for nasm.
+}
+
+config("default_crt") {
+  # This is for nasm.
+}
+
 # Linker flags for Windows SDK setup, this is applied only to EXEs and DLLs.
 config("sdk_link") {
   if (cpu_arch == "x64") {
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index a6d727c..128e68f 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -14,6 +14,8 @@
 char kTSanDefaultSuppressions[] =
   "race:third_party/glog/src/vlog_is_on.cc\n"
   "race:third_party/glog/src/raw_logging.cc\n"
+  // b/124806470
+  "race:third_party/abseil/src/absl/base/internal/spinlock.h\n"
   // goma_fetch sometimes show data race in buildbot, which we cannot reproduce
   // on our local machine (b/74301421).
   "race:PollEvents\n"
diff --git a/client/BUILD.gn b/client/BUILD.gn
index 0a77dec..2738574 100644
--- a/client/BUILD.gn
+++ b/client/BUILD.gn
@@ -479,7 +479,7 @@
     "//client/linker/linker_input_processor:linker_input_processor_lib",
     "//client/linker/linker_input_processor:thinlto_import_processor_lib",
     "//lib:compiler_flag_type_specific",
-    "//third_party:minizip",
+    "//third_party:zlib",
     "//third_party/abseil",
     "//third_party/boringssl",
     "//third_party/chromium_base:cpu",
@@ -675,7 +675,7 @@
     ":common",
     "//lib",
     "//third_party:glog",
-    "//third_party:minizip",
+    "//third_party:zlib",
   ]
 }
 
diff --git a/client/clang_tidy/clang_tidy_compiler_type_specific.h b/client/clang_tidy/clang_tidy_compiler_type_specific.h
index 650d253..6837a42 100644
--- a/client/clang_tidy/clang_tidy_compiler_type_specific.h
+++ b/client/clang_tidy/clang_tidy_compiler_type_specific.h
@@ -15,6 +15,12 @@
   ClangTidyCompilerTypeSpecific(const ClangTidyCompilerTypeSpecific&) = delete;
   void operator=(const ClangTidyCompilerTypeSpecific&) = delete;
 
+  bool RemoteCompileSupported(const string& trace_id,
+                              const CompilerFlags& flags,
+                              bool verify_output) const override {
+    return true;
+  }
+
   std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
       const string& local_compiler_path,
diff --git a/client/compile_service.cc b/client/compile_service.cc
index 890b79a..c302130 100644
--- a/client/compile_service.cc
+++ b/client/compile_service.cc
@@ -736,13 +736,13 @@
   (*ss) << " fallback_in_setup:" << std::endl
         << "  parse_fail=" << fallback_in_setup.failed_to_parse_flags()
         << " no_remote=" << fallback_in_setup.no_remote_compile_supported()
-        << " http_disabled=" << fallback_in_setup.http_disabled()
-        << std::endl
+        << " http_disabled=" << fallback_in_setup.http_disabled() << std::endl
         << "  compiler_info_fail="
         << fallback_in_setup.fail_to_get_compiler_info()
         << " compiler_disabled=" << fallback_in_setup.compiler_disabled()
         << " requested_by_user=" << fallback_in_setup.requested_by_user()
-        << std::endl;
+        << " update_required_files="
+        << fallback_in_setup.failed_to_update_required_files() << std::endl;
   (*ss) << " local:"
         << " run=" << gstats.request_stats().local().run()
         << " killed=" << gstats.request_stats().local().killed()
@@ -1566,6 +1566,8 @@
         num_forced_fallback_in_setup_[kCompilerDisabled]);
     fallback->set_requested_by_user(
         num_forced_fallback_in_setup_[kRequestedByUser]);
+    fallback->set_failed_to_update_required_files(
+        num_forced_fallback_in_setup_[KFailToUpdateRequiredFiles]);
     FileStats* files = stats->mutable_file_stats();
     files->set_requested(num_file_requested_);
     files->set_uploaded(num_file_uploaded_);
diff --git a/client/compile_service.h b/client/compile_service.h
index 0d9da8f..0d65f1c 100644
--- a/client/compile_service.h
+++ b/client/compile_service.h
@@ -77,6 +77,7 @@
     kFailToGetCompilerInfo,
     kCompilerDisabled,
     kRequestedByUser,
+    KFailToUpdateRequiredFiles,
 
     kNumForcedFallbackReasonInSetup,
   };
@@ -258,10 +259,6 @@
     store_local_run_output_ = store_local_run_output;
   }
   bool store_local_run_output() const { return store_local_run_output_; }
-  void SetEnableRemoteLink(bool enable_remote_link) {
-    enable_remote_link_ = enable_remote_link;
-  }
-  bool enable_remote_link() const { return enable_remote_link_; }
 
   void SetShouldFailForUnsupportedCompilerFlag(bool f) {
     should_fail_for_unsupported_compiler_flag_ = f;
@@ -497,6 +494,9 @@
   bool need_to_send_content_ = false;
   absl::Duration new_file_threshold_duration_;
   std::vector<absl::Duration> timeouts_;
+  // TODO: moving enable_gch_hack to compiler specific place.
+  //                    The code using the flag scatters in compile_task.
+  //                    It is difficult to omit all the use case in one CL.
   bool enable_gch_hack_;
   bool use_relative_paths_in_argv_ = false;
   bool send_expected_outputs_ = false;
@@ -517,7 +517,6 @@
   bool local_run_for_failed_input_ = false;
   absl::Duration local_run_delay_;
   bool store_local_run_output_ = false;
-  bool enable_remote_link_ = false;
   bool should_fail_for_unsupported_compiler_flag_ = false;
   string tmp_dir_;
 
diff --git a/client/compile_task.cc b/client/compile_task.cc
index 2397922..ca86e2e 100644
--- a/client/compile_task.cc
+++ b/client/compile_task.cc
@@ -350,6 +350,8 @@
 #endif
 
   requester_info_ = req_->requester_info();
+
+  InitCompilerFlags();
 }
 
 void CompileTask::Start() {
@@ -386,7 +388,6 @@
 
   gomacc_pid_ = requester_info_.pid();
 
-  InitCompilerFlags();
   if (flags_.get() == nullptr) {
     LOG(ERROR) << trace_id_ << " Start error: CompilerFlags is nullptr";
     AddErrorToResponse(TO_USER, "Unsupported command", true);
@@ -403,7 +404,7 @@
   if (!flags_->is_successful()) {
     LOG(WARNING) << trace_id_ << " Start error:" << flags_->fail_message();
     // It should fallback.
-  } else if (precompiling_) {
+  } else if (flags_->is_precompiling_header()) {
     LOG(INFO) << trace_id_ << " Start precompile "
               << (flags_->input_filenames().empty() ? "(no input)" :
                   flags_->input_filenames()[0])
@@ -444,7 +445,7 @@
         AddErrorToResponse(TO_LOG, "Precompile to no *.gch output", false);
       }
     }
-  } else if (linking_) {
+  } else if (flags_->is_linking()) {
     // build_dir will be used to infer the build directory
     // in `goma_ctl.py report`. See b/25487955.
     LOG(INFO) << trace_id_ << " Start linking "
@@ -504,7 +505,7 @@
     // we don't call goma rpc.
     return;
   }
-  if (precompiling_ && service_->enable_gch_hack()) {
+  if (flags_->is_precompiling_header() && service_->enable_gch_hack()) {
     VLOG(1) << trace_id_ << " gch hack";
     SetupSubProcess();
     RunSubProcess("gch hack");
@@ -637,7 +638,7 @@
 
 void CompileTask::TryProcessFileRequest() {
   file_request_timer_.Start();
-  if (linking_) {
+  if (flags_->is_linking()) {
     AUTOLOCK(lock, &global_mu_);
     DCHECK(link_file_req_tasks_ != nullptr);
     link_file_req_tasks_->push_back(this);
@@ -771,10 +772,10 @@
     // In linking, we'll use hash_key instead of content in ExecReq to prevent
     // from bloating ExecReq.
     VLOG(1) << trace_id_ << " input file:" << abs_filename
-            << (linking_ ? " [linking]" : "");
+            << (flags_->is_linking() ? " [linking]" : "");
     bool is_new_file = false;
     if (mtime.has_value()) {
-      if (linking_) {
+      if (flags_->is_linking()) {
         // For linking, we assume input files is old if it is older than
         // compiler_proxy start time. (i.e. it would be built in previous
         // build session, so that the files were generated by goma backends
@@ -790,11 +791,11 @@
 
     InputFileTask* input_file_task = InputFileTask::NewInputFileTask(
         service_->wm(),
-        service_->blob_client()->NewUploader(
-            abs_filename, requester_info_, trace_id_),
+        service_->blob_client()->NewUploader(abs_filename, requester_info_,
+                                             trace_id_),
         service_->file_hash_cache(), input_file_stat_cache_->Get(abs_filename),
-        abs_filename, missed_content, linking_, is_new_file, hash_key, this,
-        input);
+        abs_filename, missed_content, flags_->is_linking(), is_new_file,
+        hash_key, this, input);
     closures.push_back(
         NewCallback(
             input_file_task,
@@ -917,7 +918,7 @@
 }
 
 void CompileTask::ProcessPendingFileRequest() {
-  if (!linking_)
+  if (!flags_->is_linking())
     return;
 
   CompileTask* pending_task = nullptr;
@@ -1384,7 +1385,7 @@
     // TODO: remove following if (!abort_).
     // I belive it should always be true, or abort_ must be protected by mutex.
     if (!abort_) {
-      if (!(precompiling_ && service_->enable_gch_hack()) &&
+      if (!(flags_->is_precompiling_header() && service_->enable_gch_hack()) &&
           IsSubprocRunning()) {
         VLOG(1) << trace_id_ << " failed to process file response,"
                 << " but subprocess running";
@@ -1516,7 +1517,7 @@
     ReplyResponse("verify done");
     return;
   }
-  if (precompiling_ && service_->enable_gch_hack()) {
+  if (flags_->is_precompiling_header() && service_->enable_gch_hack()) {
     // In gch hack mode, we'll run both local and remote simultaneously.
     if (subproc_ != nullptr) {
       // subprocess still running.
@@ -2361,13 +2362,7 @@
       service_->compiler_type_specific_collection()->Get(flags_->type());
 
   flag_dump_ = flags_->DebugString();
-  if (flags_->type() == CompilerFlagType::Gcc) {
-    const GCCFlags& gcc_flag = static_cast<const GCCFlags&>(*flags_);
-    linking_ = (gcc_flag.mode() == GCCFlags::LINK);
-    precompiling_ = gcc_flag.is_precompiling_header();
-  } else if (flags_->type() == CompilerFlagType::Clexe) {
-    // TODO: check linking_ etc.
-  } else if (flags_->type() == CompilerFlagType::ClangTidy) {
+  if (flags_->type() == CompilerFlagType::ClangTidy) {
     InitClangTidyFlags(static_cast<ClangTidyFlags*>(flags_.get()));
   }
 
@@ -2463,85 +2458,12 @@
               << " force fallback. no input files give.";
     return true;
   }
-  if (flags_->type() == CompilerFlagType::Gcc) {
-    const GCCFlags& gcc_flag = static_cast<const GCCFlags&>(*flags_);
-    if (gcc_flag.is_stdin_input()) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback."
-                << " cannot use stdin as input in goma backend.";
-      return true;
-    }
-    if (gcc_flag.has_wrapper()) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback. -wrapper is not supported";
-      return true;
-    }
-    if (!verify_output_ && gcc_flag.mode() == GCCFlags::PREPROCESS) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback. preprocess is usually light-weight.";
-      return true;
-    }
-    if (!service_->enable_gch_hack() && precompiling_) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback. gch hack is not enabled and precompiling.";
-      return true;
-    }
-    if (!service_->enable_remote_link() && linking_) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback linking.";
-      return true;
-    }
-    absl::string_view ext = file::Extension(flags_->input_filenames()[0]);
-    if (ext == "s" || ext == "S") {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback. assembler should be light-weight.";
-      return true;
-    }
-  } else if (flags_->type() == CompilerFlagType::Clexe) {
-    const VCFlags& vc_flag = static_cast<const VCFlags&>(*flags_);
-    // GOMA doesn't work with PCH so we generate it only for local builds.
-    if (!vc_flag.creating_pch().empty()) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback. cannot create pch in goma backend.";
-      return true;
-    }
-    if (vc_flag.require_mspdbserv()) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback. cannot run mspdbserv in goma backend.";
-      return true;
-    }
-  } else if (flags_->type() == CompilerFlagType::Javac) {
-    const JavacFlags& javac_flag = static_cast<const JavacFlags&>(*flags_);
-    // TODO: remove following code when goma backend get ready.
-    // Force fallback a compile request with -processor (b/38215808)
-    if (!javac_flag.processors().empty()) {
-      service_->RecordForcedFallbackInSetup(
-          CompileService::kNoRemoteCompileSupported);
-      LOG(INFO) << trace_id_
-                << " force fallback to avoid running annotation processor in"
-                << " goma backend (b/38215808)";
-      return true;
-    }
-  } else if (flags_->type() == CompilerFlagType::Java) {
+  if (!compiler_type_specific_->RemoteCompileSupported(trace_id_, *flags_,
+                                                       verify_output_)) {
+    service_->RecordForcedFallbackInSetup(
+        CompileService::kNoRemoteCompileSupported);
     LOG(INFO) << trace_id_
-              << " force fallback to avoid running java program in"
-              << " goma backend";
+              << " force fallback. due to compiler specific reason.";
     return true;
   }
 
@@ -2593,7 +2515,7 @@
 SubProcessReq::Weight CompileTask::GetTaskWeight() const {
   CHECK_EQ(INIT, state_);
   int weight_score = req_->arg_size();
-  if (linking_)
+  if (flags_->is_linking())
     weight_score *= 10;
 
   if (weight_score > 1000)
@@ -2604,7 +2526,7 @@
 bool CompileTask::ShouldStopGoma() const {
   if (verify_output_)
     return false;
-  if (precompiling_ && service_->enable_gch_hack())
+  if (flags_->is_precompiling_header() && service_->enable_gch_hack())
     return false;
   if (subproc_ == nullptr) {
     DCHECK(!abort_);
@@ -2772,8 +2694,12 @@
   if (!ok) {
     // Failed to update required_files.
     if (requester_env_.verify_command().empty()) {
-      LOG(INFO) << trace_id_ << " failed to update required files. ";
-      should_fallback_ = true;
+      if (!canceled_) {
+        LOG(INFO) << trace_id_ << " failed to update required files. ";
+        service_->RecordForcedFallbackInSetup(
+            CompileService::KFailToUpdateRequiredFiles);
+        should_fallback_ = true;
+      }
       SetupRequestDone(false);
       return;
     }
@@ -4263,7 +4189,7 @@
     }
   }
 
-  if (precompiling_ && service_->enable_gch_hack()) {
+  if (flags_->is_precompiling_header() && service_->enable_gch_hack()) {
     CHECK_LT(state_, FINISHED) << trace_id_ << " finish subproc";
     CHECK(subproc_ == nullptr) << trace_id_ << " finish subproc";
     // local runs done, not yet goma.
diff --git a/client/compile_task.h b/client/compile_task.h
index 16ae3a6..2ae45e2 100644
--- a/client/compile_task.h
+++ b/client/compile_task.h
@@ -357,8 +357,6 @@
   RequesterEnv requester_env_;
 
   std::unique_ptr<CompilerFlags> flags_;
-  bool linking_ = false;
-  bool precompiling_ = false;
 
   CompilerTypeSpecific* compiler_type_specific_ = nullptr;
 
@@ -379,7 +377,7 @@
   std::unique_ptr<FileStatCache> input_file_stat_cache_;
   std::unique_ptr<FileStatCache> output_file_stat_cache_;
 
-  // |system_library_paths_| is used only when linking_ == true.
+  // |system_library_paths_| is used only when flags_->is_linking() == true.
   std::vector<string> system_library_paths_;
   // list of interleave uploaded files_to confirm the mechanism works fine.
   absl::flat_hash_set<string> interleave_uploaded_files_;
diff --git a/client/compile_task_unittest.cc b/client/compile_task_unittest.cc
index 4ac505e..033f7c4 100644
--- a/client/compile_task_unittest.cc
+++ b/client/compile_task_unittest.cc
@@ -29,6 +29,21 @@
 
 constexpr int kCompileTaskId = 1234;
 
+std::unique_ptr<ExecReq> CreateExecReqForTest() {
+  auto req = absl::make_unique<ExecReq>();
+  req->add_arg("clang");
+  req->add_arg("foo.cc");
+  req->add_arg("-o");
+  req->add_arg("foo");
+  req->set_cwd("/home/user/code/chromium/src");
+
+  auto input = req->add_input();
+  input->set_filename("foo.cc");
+  input->set_hash_key("abcdef");
+
+  return req;
+}
+
 class DummyHttpHandler : public ThreadpoolHttpServer::HttpHandler {
  public:
   ~DummyHttpHandler() override = default;
@@ -112,7 +127,7 @@
         absl::make_unique<RpcController>(http_server_request_.get());
 
     compile_task_ = new CompileTask(compile_service_.get(), kCompileTaskId);
-    auto req = absl::make_unique<ExecReq>(exec_request_);
+    auto req = CreateExecReqForTest();
     compile_task_->Init(rpc_controller_.get(), std::move(req), &exec_response_,
                         nullptr);
   }
@@ -161,7 +176,8 @@
   Json::Value json;
   compile_task()->DumpToJson(false, &json);
 
-  EXPECT_EQ(4, json.getMemberNames().size()) << json.toStyledString();
+  EXPECT_EQ(5, json.getMemberNames().size()) << json.toStyledString();
+  EXPECT_TRUE(json.isMember("command"));
   EXPECT_TRUE(json.isMember("elapsed"));
   EXPECT_TRUE(json.isMember("id"));
   EXPECT_TRUE(json.isMember("state"));
diff --git a/client/compiler_proxy_http_handler.cc b/client/compiler_proxy_http_handler.cc
index 921a1bd..c4abc26 100644
--- a/client/compiler_proxy_http_handler.cc
+++ b/client/compiler_proxy_http_handler.cc
@@ -25,6 +25,7 @@
 #include "compilerz_script.h"
 #include "compilerz_style.h"
 #include "counterz.h"
+#include "cxx/gcc_compiler_type_specific.h"
 #include "cxx/include_processor/cpp_directive_optimizer.h"
 #include "cxx/include_processor/cpp_include_processor.h"
 #include "cxx/include_processor/cpp_macro.h"
@@ -270,7 +271,6 @@
   service_.SetLocalRunDelay(absl::Milliseconds(FLAGS_LOCAL_RUN_DELAY_MSEC));
   service_.SetMaxSumOutputSize(FLAGS_MAX_SUM_OUTPUT_SIZE_IN_MB * 1024 * 1024);
   service_.SetStoreLocalRunOutput(FLAGS_STORE_LOCAL_RUN_OUTPUT);
-  service_.SetEnableRemoteLink(FLAGS_ENABLE_REMOTE_LINK);
   service_.SetShouldFailForUnsupportedCompilerFlag(
       FLAGS_FAIL_FOR_UNSUPPORTED_COMPILER_FLAGS);
   service_.SetTmpDir(tmpdir_);
@@ -321,7 +321,9 @@
     LOG(INFO) << "memory tracker disabled";
   }
 
-  CppIncludeProcessor::SetDefaultEnableClangModules(
+  GCCCompilerTypeSpecific::SetEnableGchHack(FLAGS_ENABLE_GCH_HACK);
+  GCCCompilerTypeSpecific::SetEnableRemoteLink(FLAGS_ENABLE_REMOTE_LINK);
+  GCCCompilerTypeSpecific::SetEnableRemoteClangModules(
       FLAGS_ENABLE_REMOTE_CLANG_MODULES);
 
   InitialPing();
diff --git a/client/compiler_type_specific.h b/client/compiler_type_specific.h
index 7cebf82..9016153 100644
--- a/client/compiler_type_specific.h
+++ b/client/compiler_type_specific.h
@@ -31,6 +31,11 @@
 
   virtual ~CompilerTypeSpecific() = default;
 
+  // Returns true if remote compile is supported.
+  virtual bool RemoteCompileSupported(const string& trace_id,
+                                      const CompilerFlags& flags,
+                                      bool verify_output) const = 0;
+
   // Builds CompilerInfoData.
   virtual std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
diff --git a/client/cxx/BUILD.gn b/client/cxx/BUILD.gn
index bfc39d0..7e5d894 100644
--- a/client/cxx/BUILD.gn
+++ b/client/cxx/BUILD.gn
@@ -70,20 +70,23 @@
   ]
 }
 
-static_library("chromeos_compiler_info_builder_helper_lib") {
-  sources = [
-    "chromeos_compiler_info_builder_helper.cc",
-    "chromeos_compiler_info_builder_helper.h",
-  ]
+if (is_linux) {
+  static_library("chromeos_compiler_info_builder_helper_lib") {
+    sources = [
+      "chromeos_compiler_info_builder_helper.cc",
+      "chromeos_compiler_info_builder_helper.h",
+    ]
 
-  deps = [
-    "//base",
-    "//third_party:glog",
-  ]
+    deps = [
+      "//third_party:glog",
+    ]
 
-  public_deps = [
-    "//third_party/abseil",
-  ]
+    public_deps = [
+      "//base",
+      "//client:compiler_info_lib",
+      "//third_party/abseil",
+    ]
+  }
 }
 
 static_library("cxx_compiler_info_builder_lib") {
@@ -115,7 +118,6 @@
     "//client:compiler_info_lib",
   ]
   deps = [
-    ":chromeos_compiler_info_builder_helper_lib",
     ":clang_compiler_info_builder_helper_lib",
     ":cxx_compiler_info_builder_lib",
     ":nacl_compiler_info_builder_helper_lib",
@@ -127,6 +129,10 @@
     "//third_party/abseil",
   ]
 
+  if (is_linux) {
+    deps += [ ":chromeos_compiler_info_builder_helper_lib" ]
+  }
+
   public_configs = [ "//client:client_config" ]
 }
 
@@ -247,15 +253,17 @@
   ]
 }
 
-executable("chromeos_compiler_info_builder_helper_unittest") {
-  testonly = true
-  sources = [
-    "chromeos_compiler_info_builder_helper_unittest.cc",
-  ]
+if (is_linux) {
+  executable("chromeos_compiler_info_builder_helper_unittest") {
+    testonly = true
+    sources = [
+      "chromeos_compiler_info_builder_helper_unittest.cc",
+    ]
 
-  deps = [
-    ":chromeos_compiler_info_builder_helper_lib",
-    "//build/config:exe_and_shlib_deps",
-    "//client:goma_test_lib",
-  ]
+    deps = [
+      ":chromeos_compiler_info_builder_helper_lib",
+      "//build/config:exe_and_shlib_deps",
+      "//client:goma_test_lib",
+    ]
+  }
 }
diff --git a/client/cxx/chromeos_compiler_info_builder_helper.cc b/client/cxx/chromeos_compiler_info_builder_helper.cc
index f510f42..3cdb22a 100644
--- a/client/cxx/chromeos_compiler_info_builder_helper.cc
+++ b/client/cxx/chromeos_compiler_info_builder_helper.cc
@@ -6,16 +6,53 @@
 
 #include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/str_split.h"
 #include "absl/strings/strip.h"
 #include "glog/logging.h"
+#include "lib/file_helper.h"
 #include "path.h"
 
-#ifdef __linux__
 #include <unistd.h>
-#endif
 
 namespace devtools_goma {
 
+namespace {
+
+bool IsKnownClangInChroot(absl::string_view local_compiler_path) {
+  return local_compiler_path == "/usr/bin/clang" ||
+         local_compiler_path == "/usr/bin/clang++" ||
+         local_compiler_path == "/usr/bin/x86_64-cros-linux-gnu-clang" ||
+         local_compiler_path == "/usr/bin/x86_64-cros-linux-gnu-clang++";
+}
+
+bool ParseEnvdPath(absl::string_view envd_path, string* path) {
+  // content is like
+  //
+  // ```
+  // PATH="/usr/x86_64-pc-linux-gnu/x86_64-cros-linux-gnu/gcc-bin/4.9.x"
+  // ROOTPATH="/usr/x86_64-pc-linux-gnu/x86_64-cros-linux-gnu/gcc-bin/4.9.x"
+  // ```
+
+  string content;
+  if (!ReadFileToString(envd_path, &content)) {
+    LOG(ERROR) << "failed to open/read " << envd_path;
+    return false;
+  }
+
+  for (absl::string_view line :
+       absl::StrSplit(content, absl::ByAnyChar("\r\n"), absl::SkipEmpty())) {
+    if (absl::ConsumePrefix(&line, "PATH=\"") &&
+        absl::ConsumeSuffix(&line, "\"")) {
+      *path = string(line);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+}  // anonymous namespace
+
 // static
 bool ChromeOSCompilerInfoBuilderHelper::IsSimpleChromeClangCommand(
     absl::string_view local_compiler_path,
@@ -98,9 +135,7 @@
 // static
 bool ChromeOSCompilerInfoBuilderHelper::IsClangInChrootEnv(
     absl::string_view local_compiler_path) {
-#ifdef __linux__
-  if (!(local_compiler_path == "/usr/bin/clang" ||
-        local_compiler_path == "/usr/bin/clang++")) {
+  if (!IsKnownClangInChroot(local_compiler_path)) {
     return false;
   }
 
@@ -110,11 +145,6 @@
   }
 
   return true;
-#else
-  // chromeos chroot should be Linux. So the other platform should not be
-  // chromeos chroot env.
-  return false;
-#endif
 }
 
 // static
@@ -122,7 +152,6 @@
     absl::string_view local_compiler_path,
     absl::string_view real_compiler_path,
     std::vector<string>* resource_paths) {
-#ifdef __linux__
   constexpr absl::string_view lib_dir = "/usr/lib64";
 
   int version;
@@ -132,18 +161,58 @@
     return false;
   }
 
-  // TODO: Use lld to list the libraries?
+  // TODO: Currently support only target = x86_64.
+  // for target=arm, we need to use other resources.
+  // check local_compiler_path, and if compiler name looks like arm,
+  // we have to use arm-like resources.
   resource_paths->push_back(
       file::JoinPath(lib_dir, absl::StrCat("libLLVM-", version, "svn.so")));
   resource_paths->push_back(file::JoinPath(lib_dir, "libc++.so.1"));
   resource_paths->push_back(file::JoinPath(lib_dir, "libc++abi.so.1"));
   resource_paths->push_back(file::JoinPath(lib_dir, "libffi.so.6"));
   resource_paths->push_back(file::JoinPath(lib_dir, "libxml2.so.2"));
+  resource_paths->push_back("/etc/env.d/gcc/.NATIVE");
+  resource_paths->push_back("/etc/env.d/05gcc-x86_64-cros-linux-gnu");
+
+  string path_from_envd;
+  if (!ParseEnvdPath("/etc/env.d/05gcc-x86_64-cros-linux-gnu",
+                     &path_from_envd)) {
+    return false;
+  }
+
+  if (local_compiler_path == "/usr/bin/x86_64-cros-linux-gnu-clang") {
+    // Actually /usr/bin/clang is called.
+    // /usr/x86_64-pc-linux-gnu/x86_64-cros-linux-gnu/gcc-bin/4.9.x/x86_64-cros-linux-gnu-clang
+    // is wrapper.
+    resource_paths->push_back("/usr/bin/clang");
+    resource_paths->push_back(
+        file::JoinPath(path_from_envd, "x86_64-cros-linux-gnu-clang"));
+  } else if (local_compiler_path == "/usr/bin/x86_64-cros-linux-gnu-clang++") {
+    // Actually /usr/bin/clang++ is called, and /usr/bin/clang can also be
+    // called. The latter 2 binaries are both wrapper.
+    resource_paths->push_back("/usr/bin/clang");
+    resource_paths->push_back("/usr/bin/clang++");
+    resource_paths->push_back(
+        file::JoinPath(path_from_envd, "x86_64-cros-linux-gnu-clang"));
+    resource_paths->push_back(
+        file::JoinPath(path_from_envd, "x86_64-cros-linux-gnu-clang++"));
+  }
 
   return true;
-#else
-  return false;
-#endif
+}
+
+// static
+void ChromeOSCompilerInfoBuilderHelper::SetAdditionalFlags(
+    absl::string_view local_compiler_path,
+    google::protobuf::RepeatedPtrField<std::string>* additional_flags) {
+  if (local_compiler_path == "/usr/bin/x86_64-cros-linux-gnu-clang" ||
+      local_compiler_path == "/usr/bin/x86_64-cros-linux-gnu-clang++") {
+    // Wrapper tries to set up ccache, but it's meaningless in goma.
+    // we have to set -noccache.
+    // TODO: chromeos toolchain should have -noccache by default
+    // if goma is enabled.
+    additional_flags->Add("-noccache");
+  }
 }
 
 }  // namespace devtools_goma
diff --git a/client/cxx/chromeos_compiler_info_builder_helper.h b/client/cxx/chromeos_compiler_info_builder_helper.h
index 30292fa..f87b3b9 100644
--- a/client/cxx/chromeos_compiler_info_builder_helper.h
+++ b/client/cxx/chromeos_compiler_info_builder_helper.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "absl/strings/string_view.h"
+#include "prototmp/compiler_info_data.pb.h"
 
 using std::string;
 
@@ -39,6 +40,10 @@
   static bool CollectChrootClangResources(absl::string_view local_compiler_path,
                                           absl::string_view real_compiler_path,
                                           std::vector<string>* resource_paths);
+
+  static void SetAdditionalFlags(
+      absl::string_view local_compiler_path,
+      google::protobuf::RepeatedPtrField<std::string>* additional_flags);
 };
 
 }  // namespace devtools_goma
diff --git a/client/cxx/gcc_compiler_info_builder.cc b/client/cxx/gcc_compiler_info_builder.cc
index 9346bbb..c818e29 100644
--- a/client/cxx/gcc_compiler_info_builder.cc
+++ b/client/cxx/gcc_compiler_info_builder.cc
@@ -6,7 +6,6 @@
 
 #include "absl/strings/match.h"
 #include "autolock_timer.h"
-#include "chromeos_compiler_info_builder_helper.h"
 #include "clang_compiler_info_builder_helper.h"
 #include "counterz.h"
 #include "gcc_flags.h"
@@ -17,6 +16,10 @@
 #include "path_resolver.h"
 #include "util.h"
 
+#ifdef __linux__
+#include "chromeos_compiler_info_builder_helper.h"
+#endif
+
 #ifdef _WIN32
 #include "posix_helper_win.h"
 #endif  // _WIN32
@@ -352,6 +355,8 @@
     NaClCompilerInfoBuilderHelper::CollectNaClClangResources(
         local_compiler_path, flags.cwd(), &resource_paths_to_collect);
   }
+
+#ifdef __linux__
   if (ChromeOSCompilerInfoBuilderHelper::IsSimpleChromeClangCommand(
           local_compiler_path, data->real_compiler_path())) {
     if (!ChromeOSCompilerInfoBuilderHelper::CollectSimpleChromeClangResources(
@@ -378,7 +383,11 @@
                  << " real_compiler_path=" << data->real_compiler_path();
       return;
     }
+
+    ChromeOSCompilerInfoBuilderHelper::SetAdditionalFlags(
+        local_compiler_path, data->mutable_additional_flags());
   }
+#endif  // __linux__
 
   absl::flat_hash_set<string> visited_paths;
   for (const auto& resource_path : resource_paths_to_collect) {
diff --git a/client/cxx/gcc_compiler_type_specific.cc b/client/cxx/gcc_compiler_type_specific.cc
index fafd3cb..a23246e 100644
--- a/client/cxx/gcc_compiler_type_specific.cc
+++ b/client/cxx/gcc_compiler_type_specific.cc
@@ -7,9 +7,50 @@
 #include "glog/logging.h"
 #include "linker/linker_input_processor/linker_input_processor.h"
 #include "linker/linker_input_processor/thinlto_import_processor.h"
+#include "path.h"
 
 namespace devtools_goma {
 
+bool GCCCompilerTypeSpecific::RemoteCompileSupported(const string& trace_id,
+                                                     const CompilerFlags& flags,
+                                                     bool verify_output) const {
+  const GCCFlags& gcc_flag = static_cast<const GCCFlags&>(flags);
+  if (gcc_flag.is_stdin_input()) {
+    LOG(INFO) << trace_id << " force fallback."
+              << " cannot use stdin as input in goma backend.";
+    return false;
+  }
+  if (gcc_flag.has_wrapper()) {
+    LOG(INFO) << trace_id << " force fallback. -wrapper is not supported";
+    return false;
+  }
+  if (!verify_output && gcc_flag.mode() == GCCFlags::PREPROCESS) {
+    LOG(INFO) << trace_id
+              << " force fallback. preprocess is usually light-weight.";
+    return false;
+  }
+  if (!enable_gch_hack_ && gcc_flag.is_precompiling_header()) {
+    LOG(INFO) << trace_id
+              << " force fallback. gch hack is not enabled and precompiling.";
+    return false;
+  }
+  if (!enable_remote_link_ && gcc_flag.is_linking()) {
+    LOG(INFO) << trace_id << " force fallback linking.";
+    return false;
+  }
+  if (!enable_remote_clang_modules_ && gcc_flag.has_fmodules()) {
+    LOG(INFO) << trace_id << " force fallback -fmodules";
+    return false;
+  }
+  absl::string_view ext = file::Extension(gcc_flag.input_filenames()[0]);
+  if (ext == "s" || ext == "S") {
+    LOG(INFO) << trace_id
+              << " force fallback. assembler should be light-weight.";
+    return false;
+  }
+  return true;
+}
+
 std::unique_ptr<CompilerInfoData>
 GCCCompilerTypeSpecific::BuildCompilerInfoData(
     const CompilerFlags& flags,
@@ -100,4 +141,13 @@
   return result;
 }
 
+// static
+bool GCCCompilerTypeSpecific::enable_gch_hack_;
+
+// static
+bool GCCCompilerTypeSpecific::enable_remote_link_;
+
+// static
+bool GCCCompilerTypeSpecific::enable_remote_clang_modules_;
+
 }  // namespace devtools_goma
diff --git a/client/cxx/gcc_compiler_type_specific.h b/client/cxx/gcc_compiler_type_specific.h
index dccbdaf..98ba457 100644
--- a/client/cxx/gcc_compiler_type_specific.h
+++ b/client/cxx/gcc_compiler_type_specific.h
@@ -15,6 +15,10 @@
   GCCCompilerTypeSpecific(const GCCCompilerTypeSpecific&) = delete;
   void operator=(const GCCCompilerTypeSpecific&) = delete;
 
+  bool RemoteCompileSupported(const string& trace_id,
+                              const CompilerFlags& flags,
+                              bool verify_output) const override;
+
   std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
       const string& local_compiler_path,
@@ -29,6 +33,16 @@
 
   bool SupportsDepsCache(const CompilerFlags& flags) const override;
 
+  static void SetEnableGchHack(bool enable_gch_hack) {
+    enable_gch_hack_ = enable_gch_hack;
+  }
+  static void SetEnableRemoteLink(bool enable_remote_link) {
+    enable_remote_link_ = enable_remote_link;
+  }
+  static void SetEnableRemoteClangModules(bool enable_remote_clang_modules) {
+    enable_remote_clang_modules_ = enable_remote_clang_modules;
+  }
+
  private:
   GCCCompilerTypeSpecific() = default;
 
@@ -43,6 +57,10 @@
   GCCCompilerInfoBuilder compiler_info_builder_;
 
   friend class CompilerTypeSpecificCollection;
+
+  static bool enable_gch_hack_;
+  static bool enable_remote_link_;
+  static bool enable_remote_clang_modules_;
 };
 
 }  // namespace devtools_goma
diff --git a/client/cxx/include_processor/cpp_include_processor.cc b/client/cxx/include_processor/cpp_include_processor.cc
index bf06be4..69a82ce 100644
--- a/client/cxx/include_processor/cpp_include_processor.cc
+++ b/client/cxx/include_processor/cpp_include_processor.cc
@@ -103,9 +103,6 @@
 
 }  // anonymous namespace
 
-// static
-bool CppIncludeProcessor::default_enable_clang_modules_;
-
 class IncludePathsObserver : public CppParser::IncludeObserver {
  public:
   IncludePathsObserver(std::string cwd,
@@ -639,16 +636,26 @@
       // -ffreestanding, otherwise stdc-predef.h's header guard will be
       // defined and this will be a no-op.
 
-      // TODO: Some environment might not have stdc-predef.h
-      // (e.g. android). In that case, IncludeProcess currently emit WARNING,
-      // but it's ignoreable. It would be better to suppress such warning.
+      // Some environment might not have stdc-predef.h (e.g. android).
+      // If cpp_parser tries including a missing file, it is considered as
+      // a hard error. So, we have to check it exists or not.
+      // gcc-4 does not have __has_include (it's from gcc-5, IIRC,
+      // see https://gcc.gnu.org/gcc-5/changes.html#c-family),
+      // but we have to try to include stdc-predef.h.
+      // So, here, we try to include stdc-predef.h anyway, and clear the error
+      // if an error has occured.
+      // See b/124756380.
       const string stdc_predef_input(
           "#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)\n"
           "#include <stdc-predef.h>\n"
           "#endif\n");
       cpp_parser_.AddStringInput(stdc_predef_input, "(stdc-predef)");
+      bool prev_disabled = cpp_parser_.disabled();
       if (!cpp_parser_.ProcessDirectives()) {
-        LOG(ERROR) << "failed to handle stdc-predef";
+        LOG(WARNING) << "failed to handle stdc-predef";
+        if (!prev_disabled) {
+          cpp_parser_.ClearDisabled();
+        }
       }
       // Since base_file_ will be updated in the last AddStringInput, we need
       // to clear it. Otherwise, test will fail.
@@ -691,11 +698,6 @@
   if (compiler_flags.type() == CompilerFlagType::Gcc) {
     const GCCFlags& flags = static_cast<const GCCFlags&>(compiler_flags);
     if (flags.has_fmodules()) {
-      if (!enable_clang_modules()) {
-        LOG(WARNING) << "-fmodules support is not enabled in compiler_proxy";
-        return false;
-      }
-
       if (!AddClangModulesFiles(flags, current_directory, include_files,
                                 file_stat_cache)) {
         return false;
diff --git a/client/cxx/include_processor/cpp_include_processor.h b/client/cxx/include_processor/cpp_include_processor.h
index 9bcba3e..c01d704 100644
--- a/client/cxx/include_processor/cpp_include_processor.h
+++ b/client/cxx/include_processor/cpp_include_processor.h
@@ -26,14 +26,7 @@
 
 class CppIncludeProcessor {
  public:
-  CppIncludeProcessor()
-      : enable_clang_modules_(default_enable_clang_modules_) {}
-
-  static void SetDefaultEnableClangModules(bool default_enable_clang_modules) {
-    default_enable_clang_modules_ = default_enable_clang_modules;
-  }
-  void set_enable_clang_modules(bool enable) { enable_clang_modules_ = enable; }
-  bool enable_clang_modules() { return enable_clang_modules_; }
+  CppIncludeProcessor() = default;
 
   // Enumerates all include files. When FileStats are created for them,
   // we cache them in |file_stat_cache| so that we can reuse them later,
@@ -64,10 +57,7 @@
                             std::set<string>* include_files,
                             FileStatCache* file_stat_cache) const;
 
-  static bool default_enable_clang_modules_;
-
   CppParser cpp_parser_;
-  bool enable_clang_modules_;
 
   friend class CppIncludeProcessorTest;
 
diff --git a/client/cxx/include_processor/cpp_include_processor_posix_unittest.cc b/client/cxx/include_processor/cpp_include_processor_posix_unittest.cc
index 2a908d2..98fd92d 100644
--- a/client/cxx/include_processor/cpp_include_processor_posix_unittest.cc
+++ b/client/cxx/include_processor/cpp_include_processor_posix_unittest.cc
@@ -217,7 +217,6 @@
     VLOG(1) << cis.get()->info().DebugString();
 
     CppIncludeProcessor processor;
-    processor.set_enable_clang_modules(true);
     std::set<string> files;
     FileStatCache file_stat_cache;
     ASSERT_TRUE(processor.GetIncludeFiles(
@@ -447,6 +446,49 @@
   EXPECT_EQ(1U, files.size());
 }
 
+TEST_F(CppIncludeProcessorPosixTest, stdcpredef_missing) {
+  const string& bare_gcc = "/usr/bin/g++";
+  const string& source_file = CreateTmpFile("", "foo.cc");
+
+  std::vector<string> args;
+  args.push_back(bare_gcc);
+  args.push_back("-I.");
+  args.push_back("-c");
+  args.push_back(source_file);
+
+  std::unique_ptr<CompilerFlags> flags(
+      CompilerFlagsParser::MustNew(args, tmpdir_util_->tmpdir()));
+  std::unique_ptr<CompilerInfoData> data(
+      CreateCompilerInfoWithArgs(*flags, bare_gcc, env_));
+
+  data->set_name("g++");
+  data->set_version("g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2");
+  data->mutable_cxx()->set_predefined_macros(
+      "#define __GNUC__ 4\n"
+      "#define __GNUC_MINOR__ 8\n");
+
+  // clear all include directories so that /usr/include/stdc-predef.h is not
+  // included.
+  data->mutable_cxx()->mutable_quote_include_paths()->Clear();
+  data->mutable_cxx()->mutable_system_include_paths()->Clear();
+  data->mutable_cxx()->mutable_cxx_system_include_paths()->Clear();
+  data->mutable_cxx()->mutable_system_framework_paths()->Clear();
+
+  CxxCompilerInfo compiler_info(std::move(data));
+
+  CppIncludeProcessor processor;
+  std::set<string> files;
+  FileStatCache file_stat_cache;
+
+  // Don't fail even if stdc-predef.h is missing.
+  ASSERT_TRUE(processor.GetIncludeFiles(source_file, tmpdir_util_->tmpdir(),
+                                        *flags, compiler_info, &files,
+                                        &file_stat_cache));
+
+  // stdc-predef.h should not be included.
+  EXPECT_EQ(0U, files.size());
+}
+
 TEST_F(CppIncludeProcessorPosixTest, ffreestanding) {
   const string& bare_gcc = "/usr/bin/g++";
   const string& source_file = CreateTmpFile("", "foo.cc");
diff --git a/client/cxx/include_processor/cpp_parser.h b/client/cxx/include_processor/cpp_parser.h
index 7c034ef..3debe1d 100644
--- a/client/cxx/include_processor/cpp_parser.h
+++ b/client/cxx/include_processor/cpp_parser.h
@@ -135,6 +135,9 @@
     return true;
   }
 
+  bool disabled() const { return disabled_; }
+  void ClearDisabled() { disabled_ = false; }
+
   int total_files() const { return total_files_; }
   int skipped_files() const { return skipped_files_; }
 
diff --git a/client/cxx/vc_compiler_type_specific.cc b/client/cxx/vc_compiler_type_specific.cc
index 186bb28..59ac7ac 100644
--- a/client/cxx/vc_compiler_type_specific.cc
+++ b/client/cxx/vc_compiler_type_specific.cc
@@ -3,9 +3,29 @@
 // found in the LICENSE file.
 
 #include "vc_compiler_type_specific.h"
+#include "glog/logging.h"
 
 namespace devtools_goma {
 
+bool VCCompilerTypeSpecific::RemoteCompileSupported(const string& trace_id,
+                                                    const CompilerFlags& flags,
+                                                    bool verify_output) const {
+  const VCFlags& vc_flag = static_cast<const VCFlags&>(flags);
+  // GOMA doesn't work with PCH so we generate it only for local builds.
+  if (!vc_flag.creating_pch().empty()) {
+    LOG(INFO) << trace_id
+              << " force fallback. cannot create pch in goma backend.";
+    return false;
+  }
+  if (vc_flag.require_mspdbserv()) {
+    LOG(INFO) << trace_id
+              << " force fallback. cannot run mspdbserv in goma backend.";
+    return false;
+  }
+
+  return true;
+}
+
 std::unique_ptr<CompilerInfoData> VCCompilerTypeSpecific::BuildCompilerInfoData(
     const CompilerFlags& flags,
     const string& local_compiler_path,
diff --git a/client/cxx/vc_compiler_type_specific.h b/client/cxx/vc_compiler_type_specific.h
index 3eefc40..0141c8b 100644
--- a/client/cxx/vc_compiler_type_specific.h
+++ b/client/cxx/vc_compiler_type_specific.h
@@ -17,6 +17,10 @@
   VCCompilerTypeSpecific(const VCCompilerTypeSpecific&) = delete;
   void operator=(const VCCompilerTypeSpecific&) = delete;
 
+  bool RemoteCompileSupported(const string& trace_id,
+                              const CompilerFlags& flags,
+                              bool verify_output) const override;
+
   std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
       const string& local_compiler_path,
diff --git a/client/fake/fake_compiler_type_specific.h b/client/fake/fake_compiler_type_specific.h
index 68dff6d..dd57c5f 100644
--- a/client/fake/fake_compiler_type_specific.h
+++ b/client/fake/fake_compiler_type_specific.h
@@ -15,6 +15,12 @@
   FakeCompilerTypeSpecific(const FakeCompilerTypeSpecific&) = delete;
   void operator=(const FakeCompilerTypeSpecific&) = delete;
 
+  bool RemoteCompileSupported(const string& trace_id,
+                              const CompilerFlags& flags,
+                              bool verify_output) const override {
+    return true;
+  }
+
   std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
       const string& local_compiler_path,
diff --git a/client/http.cc b/client/http.cc
index bb5529e..4cb9ed0 100644
--- a/client/http.cc
+++ b/client/http.cc
@@ -1086,9 +1086,9 @@
 
   UpdateStatusCodeHistoryUnlocked();
 
-  return bad_status_num_in_recent_http_ <=
-      recent_http_status_code_.size() *
-      options_.network_error_threshold_percent / 100;
+  return bad_status_num_in_recent_http_ * 100 <=
+         recent_http_status_code_.size() *
+             options_.network_error_threshold_percent;
 }
 
 bool HttpClient::IsHealthy() const {
diff --git a/client/java/java_compiler_type_specific.cc b/client/java/java_compiler_type_specific.cc
index 0f54991..8bf3765 100644
--- a/client/java/java_compiler_type_specific.cc
+++ b/client/java/java_compiler_type_specific.cc
@@ -10,6 +10,15 @@
 
 namespace devtools_goma {
 
+bool JavaCompilerTypeSpecific::RemoteCompileSupported(
+    const string& trace_id,
+    const CompilerFlags& flags,
+    bool verify_output) const {
+  LOG(INFO) << trace_id << " force fallback to avoid running java program in"
+            << " goma backend";
+  return false;
+}
+
 std::unique_ptr<CompilerInfoData>
 JavaCompilerTypeSpecific::BuildCompilerInfoData(
     const CompilerFlags& flags,
@@ -35,6 +44,22 @@
 
 // ----------------------------------------------------------------------
 
+bool JavacCompilerTypeSpecific::RemoteCompileSupported(
+    const string& trace_id,
+    const CompilerFlags& flags,
+    bool verify_output) const {
+  const JavacFlags& javac_flag = static_cast<const JavacFlags&>(flags);
+  // TODO: remove following code when goma backend get ready.
+  // Force fallback a compile request with -processor (b/38215808)
+  if (!javac_flag.processors().empty()) {
+    LOG(INFO) << trace_id
+              << " force fallback to avoid running annotation processor in"
+              << " goma backend (b/38215808)";
+    return false;
+  }
+  return true;
+}
+
 std::unique_ptr<CompilerInfoData>
 JavacCompilerTypeSpecific::BuildCompilerInfoData(
     const CompilerFlags& flags,
diff --git a/client/java/java_compiler_type_specific.h b/client/java/java_compiler_type_specific.h
index c31b704..a4ee39e 100644
--- a/client/java/java_compiler_type_specific.h
+++ b/client/java/java_compiler_type_specific.h
@@ -15,6 +15,10 @@
   JavaCompilerTypeSpecific(const JavaCompilerTypeSpecific&) = delete;
   void operator=(const JavaCompilerTypeSpecific&) = delete;
 
+  bool RemoteCompileSupported(const string& trace_id,
+                              const CompilerFlags& flags,
+                              bool verify_output) const override;
+
   std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
       const string& local_compiler_path,
@@ -42,6 +46,10 @@
   JavacCompilerTypeSpecific(const JavacCompilerTypeSpecific&) = delete;
   void operator=(const JavacCompilerTypeSpecific&) = delete;
 
+  bool RemoteCompileSupported(const string& trace_id,
+                              const CompilerFlags& flags,
+                              bool verify_output) const override;
+
   std::unique_ptr<CompilerInfoData> BuildCompilerInfoData(
       const CompilerFlags& flags,
       const string& local_compiler_path,
diff --git a/client/resources/compiler_proxy_status_script.js b/client/resources/compiler_proxy_status_script.js
index 9c0164f..9945123 100644
--- a/client/resources/compiler_proxy_status_script.js
+++ b/client/resources/compiler_proxy_status_script.js
@@ -89,7 +89,7 @@
  * @return {string} task status
  */
 function taskStatus(task) {
-  // There is a case that `canceled` exists but `exit` or `http` does not
+  // There is a case that `canceled` exists but `exit` or `http_status` does not
   // exists. So handle this earlier.
   if (task['canceled']) {
     return 'cancel';
@@ -105,8 +105,8 @@
     if (task['exit'] != 0) {
       success = false;
     }
-  } else if ('http' in task) {
-    if (task['http'] != 200) {
+  } else if ('http_status' in task) {
+    if (task['http_status'] != 200) {
       success = false;
     }
   }
@@ -115,7 +115,10 @@
     return 'client-error'
   }
   if (task['goma_error']) {
-    if (task['http'] != 200) {
+    if (!('http_status' in task)) {
+      return 'conftestfailure'
+    }
+    if (task['http_status'] != 200) {
       return 'http-error';
     }
     return 'backend-error'
diff --git a/client/task/input_file_task.cc b/client/task/input_file_task.cc
index 7c162db..bd710f6 100644
--- a/client/task/input_file_task.cc
+++ b/client/task/input_file_task.cc
@@ -13,6 +13,18 @@
 
 namespace devtools_goma {
 
+namespace {
+
+// For file sizes no larger than this limit, embed it in the request instead of
+// uploading separately.
+constexpr size_t kLargeFileThreshold = 2 * 1024 * 1024UL;  // 2MB
+
+// For file sizes smaller than this limit, embed it in the request even if only
+// the hash key was requested.
+constexpr size_t kTinyFileThreshold = 512;
+
+}  // anonymous namespace
+
 // static
 InputFileTask* InputFileTask::NewInputFileTask(
     WorkerThreadManager* wm,
@@ -93,7 +105,7 @@
   }
 
   if (need_to_upload_content(hash_key)) {
-    if (need_hash_only_ || file_stat_.size > 2 * 1024 * 1024) {
+    if (need_hash_only_ || file_stat_.size > kLargeFileThreshold) {
       // upload in side channel.
       LOG(INFO) << task->trace_id() << "(" << num_tasks() << " tasks)"
                 << " upload:" << filename_ << " size:" << file_stat_.size
@@ -109,8 +121,8 @@
                 << " reason:" << upload_reason(hash_key);
       success_ = blob_uploader_->Embed();
     }
-  } else if (file_stat_.size < 512) {
-    // For small size of file blob, embed it even if the copmile task
+  } else if (file_stat_.size < kTinyFileThreshold) {
+    // For small size of file blob, embed it even if the compile task
     // requested hash key only.
     LOG(INFO) << task->trace_id() << " (" << num_tasks() << " tasks)"
               << " embed:" << filename_ << " size:" << file_stat_.size
@@ -224,7 +236,7 @@
     // we'll calculate hash key during uploading.
     return false;
   }
-  return file_stat_.size >= 512;
+  return file_stat_.size >= kTinyFileThreshold;
 }
 
 bool InputFileTask::need_to_upload_content(absl::string_view hash_key) const {
diff --git a/doc/include-processor.md b/doc/include-processor.md
new file mode 100644
index 0000000..baa8560
--- /dev/null
+++ b/doc/include-processor.md
@@ -0,0 +1,128 @@
+# How C/C++ IncludeProcessor works
+
+This document describes the current status of
+[C/C++ IncludeProcessor](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor).
+
+This document is based on
+[the goma client revision on Feb 2019](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26
+).
+
+## Purpose of C/C++ IncludeProcessor
+
+The purpose of C/C++ IncludeProcessor is to list all necessary included files.
+For example, if `#include <foo.h>` is found, "foo.h" is listed as an
+include file.
+
+```c++
+#include <foo.h>
+```
+
+However, there are a few conditionally included files. For example:
+
+```c++
+#if FOO() && BAR()
+#include <baz.h>
+#endif
+```
+
+In this case, only when `FOO() && BAR()` is true, `baz.h` is included.
+So, C/C++ IncludeProcessor needs to evaluate preprocessor directives.
+
+In the rest of this document, we describe how this evalution works.
+
+## Convert a file content to a list of CppDirective
+
+Assume C/C++ IncludeProcessor wants to list included files for a file "a.cc".
+
+First, we convert "a.cc" content to `IncludeItem`.
+`IncludeItem` contains `SharedCppDirectives`, and detected include guard
+(if any). `SharedCppDirectives` is conceptually a list of `CppDirective`.
+One `CppDirective` corresponds to one cpp directive e.g. `#include <iostream>`.
+
+Definition is the following:
+
+```c++
+using CppDirectiveList = std::vector<std::unique_ptr<const CppDirective>>;
+using SharedCppDirectives = std::shared_ptr<const CppDirectiveList>;
+```
+
+See: [cpp_directive.h](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/cpp_directive.h)
+
+Process flow is like the following: See IncludeCache::CreateFromFile for more
+details.
+
+```
+Input File
+  v
+  v  DirectiveFilter: Keep only # lines to make parser faster.
+  v
+Input File (filtered)
+  v
+  v  CppDirectiveParser: parse # lines and convert them to a list of
+  v  CppDirective.
+  v
+SharedCppDirectives
+  v
+  v  CppDirectiveOptimizer: remove unnecessary directives,
+  v  which won't affect include processor result.
+  v
+SharedCppDirectives
+  v
+  v  IncludeGuardDetector: detect include guard to use in CppParser.
+  v
+IncludeItem
+```
+
+The result is cached in
+[IncludeCache](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/include_cache.h),
+and we reuse the conversion result to process the same file.
+
+The cache size is limited by the max number of entries.
+After processing all chrome sources, 200~300 MB
+will be used in IncludeCache.
+
+## Evaluate a list of CppDirective
+
+After a file can be converted to a list of CppDirectives,
+[`CppParser`](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/cpp_parser.h#)
+evaluates the list of `CppDirectives`.
+
+Evaluation is just processing CppDirectives one by one.
+See [`CppParser::ProcessDirectives`](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/cpp_parser.cc#114),
+to understand how evalution works.
+
+During evaluation, CppParser keeps a hashmap from macro name (string) to Macro.
+For example, `#define A FOO BAR` is processed,
+`CppParser` has a hashmap entry like
+`"A" --> Macro(tokens=["FOO", "BAR"])`.
+
+Note that we pass directives not only from a file input, but also from
+a compiler predefined macros (e.g. `__cplusplus`) and
+macros defined in a command line flag (e.g. `-DFOO=BAR`).
+We need to pass these predefined macros and command line defined macros to
+CppParser before evaluating CppDirective from a file input.
+
+### Memory usage
+
+On Linux, the mean size of the hashmap is around 4000 entries.
+On Windows, since windows.h is large, it sometimes exceeds 15000 entries.
+
+If the mean memory size of macro entry is just 1KB, macro environment will use
+1 \[KB\] * 15,000 \[bytes/entries\] = 15 MB (+ hashmap overhead).
+IncludeProcessor works in parallel (usually the number of CPU cores tasks).
+If you're using 32 cores machine, 32 * 15 = 480 MB will be used.
+Note that this is rough estimation.
+
+## How to expand macro
+
+[`CppParser::ProcessDirectives`](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/cpp_parser.cc#114)
+just evaluates each directives, so it's easy.
+However, one difficult point is how to expand macro.
+
+Macro expansion uses two different expanders:
+[CppMacroExpanderCBV](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/cpp_macro_expander_cbv.h)
+and
+[CppMacroExpanderNaive](https://chromium.googlesource.com/infra/goma/client/+/01dbe2875fb5aaa3a3bd125b40afca28ce2faa26/client/cxx/include_processor/cpp_macro_expander_naive.h).
+
+See comment about how they work. Especially, CBV version has several examples.
+Naive version is based on https://www.spinellis.gr/blog/20060626/cpp.algo.pdf.
diff --git a/lib/compiler_flags.h b/lib/compiler_flags.h
index a5b0032..90da17a 100644
--- a/lib/compiler_flags.h
+++ b/lib/compiler_flags.h
@@ -83,6 +83,11 @@
   // compiler_proxy to goma server.
   virtual bool IsServerImportantEnv(const char* env) const = 0;
 
+  // The compiler command is a link operation.
+  virtual bool is_linking() const { return false; }
+  // The compiler command is precompiling a header.
+  virtual bool is_precompiling_header() const { return false; }
+
   // Copy client important environment variables from |envp| to |out_envs|.
   void GetClientImportantEnvs(const char** envp,
                               std::vector<string>* out_envs) const;
diff --git a/lib/gcc_flags.h b/lib/gcc_flags.h
index 6773af8..655d051 100644
--- a/lib/gcc_flags.h
+++ b/lib/gcc_flags.h
@@ -63,7 +63,10 @@
   bool has_resource_dir() const { return !resource_dir_.empty(); }
   bool has_wrapper() const { return has_wrapper_; }
   bool has_fplugin() const { return has_fplugin_; }
-  bool is_precompiling_header() const { return is_precompiling_header_; }
+  bool is_linking() const override { return mode_ == GCCFlags::LINK; }
+  bool is_precompiling_header() const override {
+    return is_precompiling_header_;
+  }
   bool is_stdin_input() const { return is_stdin_input_; }
 
   bool has_fmodules() const { return has_fmodules_; }
diff --git a/lib/goma_stats.proto b/lib/goma_stats.proto
index 0d46c9a..4621ab7 100644
--- a/lib/goma_stats.proto
+++ b/lib/goma_stats.proto
@@ -90,7 +90,7 @@
 }
 
 // Statistics on forced local fallbacks in setup step.
-// NEXT ID TO USE: 7
+// NEXT ID TO USE: 8
 message FallbackInSetupStats {
   // Number of fallbacks caused by failures to parse command line flags.
   optional int64 failed_to_parse_flags = 1;
@@ -104,6 +104,8 @@
   optional int64 compiler_disabled = 5;
   // Number of fallbacks requested by the user.
   optional int64 requested_by_user = 6;
+  // Number of fallbacks caused by failures to update required files.
+  optional int64 failed_to_update_required_files = 7;
 }
 
 // Statistics of files used for remote compile.
diff --git a/lib/vc_flags.h b/lib/vc_flags.h
index 0babbc2..1a5fda9 100644
--- a/lib/vc_flags.h
+++ b/lib/vc_flags.h
@@ -50,6 +50,8 @@
 
   const string& implicit_macros() const { return implicit_macros_; }
 
+  // TODO: check flags_->is_linking() etc.
+
   static bool IsClangClCommand(absl::string_view arg);
   static bool IsVCCommand(absl::string_view arg);
   static string GetCompilerName(absl::string_view arg);
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 0236f98..0e6167c 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -12,8 +12,8 @@
 llvm-build
 lss
 markupsafe
+nasm
 protobuf/protobuf
 subprocess32
 xz
-yasm/source/patched-yasm
 zlib
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index 9521f66..bc9a072 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -218,54 +218,6 @@
   configs += [ "//build/config/compiler:no_goma_code" ]
 }
 
-config("minizip_config") {
-  defines = [ "ZLIB_CONST" ]
-  include_dirs = [
-    "//third_party/zlib",
-    "//third_party/zlib/contrib",
-  ]
-}
-static_library("minizip") {
-  sources = [
-    "zlib/adler32.c",
-    "zlib/contrib/minizip/ioapi.c",
-    "zlib/contrib/minizip/ioapi.h",
-    "zlib/contrib/minizip/unzip.c",
-    "zlib/contrib/minizip/unzip.h",
-    "zlib/crc32.c",
-    "zlib/deflate.c",
-    "zlib/gzlib.c",
-    "zlib/gzwrite.c",
-    "zlib/infback.c",
-    "zlib/inffast.c",
-    "zlib/inflate.c",
-    "zlib/inftrees.c",
-    "zlib/trees.c",
-    "zlib/zconf.h",
-    "zlib/zlib.h",
-    "zlib/zutil.c",
-  ]
-  include_dirs = [ "//third_party/zlib/contrib/minizip" ]
-  defines = [ "USE_FILE32API" ]
-  public_configs = [ ":minizip_config" ]
-  if (os == "win") {
-    cflags = [
-      "/wd4013",  # "open" etc undefined; assuming extern returning int
-      "/wd4244",  # conversion from "ZPOS64_T" to "long", possible loss of data
-    ]
-    sources += [ "zlib/contrib/minizip/iowin32.c" ]
-  }
-  if (is_posix) {
-    cflags = [
-      "-includeunistd.h",  # for lseek, write and close.
-      "-Wno-shift-negative-value",  # inflateMark returns -1 << 16.
-    ]
-  }
-
-  configs -= [ "//build/config/compiler:goma_code" ]
-  configs += [ "//build/config/compiler:no_goma_code" ]
-}
-
 config("liblzma_config") {
   include_dirs = [ "xz/src/liblzma/api" ]
 }
@@ -441,3 +393,152 @@
     }
   }
 }
+
+# copied from zlib's BUILD.gn and modified for Goma.
+# TODO: remove this if dependency issue has been fixed.
+
+# Copyright (c) 2013 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.
+
+config("zlib_config") {
+  defines = [ "ZLIB_CONST" ]
+  include_dirs = [
+    "//third_party/zlib",
+    "//third_party/zlib/contrib",
+  ]
+}
+
+static_library("zlib_x86_simd") {
+  if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    sources = [
+      "zlib/crc_folding.c",
+
+      # Added followings to mitigate gn check failure.
+      "zlib/deflate.h",
+      "zlib/fill_window_sse.c",
+      "zlib/zlib.h",
+      "zlib/zutil.h",
+    ]
+    if (!is_win || is_clang) {
+      cflags = [
+        "-msse4.2",
+        "-mpclmul",
+      ]
+    }
+  } else {
+    sources = [
+      "zlib/simd_stub.c",
+    ]
+  }
+
+  configs -= [ "//build/config/compiler:goma_code" ]
+  configs += [ "//build/config/compiler:no_goma_code" ]
+}
+
+config("zlib_warnings") {
+  if (is_clang && !is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    cflags = [ "-Wno-incompatible-pointer-types" ]
+  }
+}
+
+static_library("zlib") {
+  if (!is_win) {
+    # Don't stomp on "libzlib" on other platforms.
+    output_name = "chrome_zlib"
+  }
+
+  sources = [
+    "zlib/adler32.c",
+    "zlib/compress.c",
+    "zlib/crc32.c",
+    "zlib/crc32.h",
+    "zlib/deflate.c",
+    "zlib/deflate.h",
+    "zlib/gzclose.c",
+    "zlib/gzguts.h",
+    "zlib/gzlib.c",
+    "zlib/gzread.c",
+    "zlib/gzwrite.c",
+    "zlib/infback.c",
+    "zlib/inffast.c",
+    "zlib/inffast.h",
+    "zlib/inffixed.h",
+    "zlib/inflate.c",
+    "zlib/inflate.h",
+    "zlib/inftrees.c",
+    "zlib/inftrees.h",
+    "zlib/names.h",
+    "zlib/trees.c",
+    "zlib/trees.h",
+    "zlib/uncompr.c",
+    "zlib/x86.h",
+    "zlib/zconf.h",
+    "zlib/zlib.h",
+    "zlib/zutil.c",
+    "zlib/zutil.h",
+  ]
+
+  if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    sources += [ "zlib/x86.c" ]
+  }
+
+  configs -= [ "//build/config/compiler:goma_code" ]
+  configs += [
+    "//build/config/compiler:no_goma_code",
+
+    # Must be after no_chromium_code for warning flags to be ordered correctly.
+    ":zlib_warnings",
+  ]
+
+  public_configs = [ ":zlib_config" ]
+  deps = [
+    ":zlib_x86_simd",
+  ]
+}
+
+config("minizip_warnings") {
+  visibility = [ ":*" ]
+  if (is_clang) {
+    # zlib uses `if ((a == b))` for some reason.
+    cflags = [ "-Wno-parentheses-equality" ]
+  }
+}
+
+static_library("minizip") {
+  sources = [
+    "zlib/contrib/minizip/ioapi.c",
+    "zlib/contrib/minizip/ioapi.h",
+    "zlib/contrib/minizip/iowin32.c",
+    "zlib/contrib/minizip/iowin32.h",
+    "zlib/contrib/minizip/unzip.c",
+    "zlib/contrib/minizip/unzip.h",
+    "zlib/contrib/minizip/zip.c",
+    "zlib/contrib/minizip/zip.h",
+  ]
+
+  if (!is_win) {
+    sources -= [
+      "zlib/contrib/minizip/iowin32.c",
+      "zlib/contrib/minizip/iowin32.h",
+    ]
+  }
+  if (is_mac || is_ios || is_android) {
+    # Mac, Android and the BSDs don't have fopen64, ftello64, or fseeko64. We
+    # use fopen, ftell, and fseek instead on these systems.
+    defines = [ "USE_FILE32API" ]
+  }
+
+  deps = [
+    ":zlib",
+  ]
+
+  configs -= [ "//build/config/compiler:goma_code" ]
+  configs += [
+    "//build/config/compiler:no_goma_code",
+
+    # Must be after no_chromium_code for warning flags to be ordered correctly.
+    ":minizip_warnings",
+  ]
+  public_configs = [ ":zlib_config" ]
+}
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
index 98d54f5..ec362ba 100644
--- a/third_party/boringssl/BUILD.gn
+++ b/third_party/boringssl/BUILD.gn
@@ -38,18 +38,18 @@
 
 all_sources = crypto_sources + ssl_sources
 
-# Windows' assembly is built with Yasm. The other platforms use the platform
-# assembler.
-if (os == "win") {
-  import("//third_party/yasm/yasm_assemble.gni")
-  yasm_assemble("boringssl_asm") {
+# Windows' assembly is built with NASM. The other platforms use the platform
+# assembler. Exclude Windows ARM64 because NASM targets x86 and x64 only.
+if (os == "win" && !is_msan) {
+  import("//third_party/nasm/nasm_assemble.gni")
+  nasm_assemble("boringssl_asm") {
     if (cpu_arch == "x64") {
       sources = crypto_sources_win_x86_64
     } else if (cpu_arch == "x86") {
       sources = crypto_sources_win_x86
     }
     if (!is_debug) {
-      yasm_flags = [ "-DNDEBUG" ]
+      nasm_flags = [ "-DNDEBUG" ]
     }
   }
 } else {
diff --git a/third_party/breakpad/BUILD.gn b/third_party/breakpad/BUILD.gn
index 7307fe5..09b01ad 100644
--- a/third_party/breakpad/BUILD.gn
+++ b/third_party/breakpad/BUILD.gn
@@ -318,8 +318,7 @@
         # not crash at -Os.  To play it safe, dump_syms is always built
         # at -O0 until this can be sorted out.
         # https://crbug.com/google-breakpad/329
-        # ORIGINAL: configs -= [ "//build/config/compiler:default_optimization" ]
-        configs -= [ "//build/config/compiler:optimize" ]
+        configs -= [ "//build/config/compiler:default_optimization" ]
         cflags += [ "-O0" ]
       }
 
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn
index 5db66c9..2dda274 100644
--- a/third_party/protobuf/BUILD.gn
+++ b/third_party/protobuf/BUILD.gn
@@ -247,7 +247,7 @@
 
   public_configs = [
     ":protobuf_config",
-    "//third_party:minizip_config",
+    "//third_party:zlib_config",
 
     # TODO: crbug.com/167187 fix size_t to int truncations.
     "//build/config/compiler:no_size_t_to_int_warning",
@@ -364,14 +364,14 @@
   }
   public_configs = [
     ":protobuf_config",
-    "//third_party:minizip_config",
+    "//third_party:zlib_config",
 
     # TODO: crbug.com/167187 fix size_t to int truncations.
     "//build/config/compiler:no_size_t_to_int_warning",
   ]
 
   deps = [
-    "//third_party:minizip",
+    "//third_party:zlib",
   ]
 
   cflags = protobuf_lite_cflags
diff --git a/third_party/yasm/BUILD.gn b/third_party/yasm/BUILD.gn
deleted file mode 100644
index 72e99b3..0000000
--- a/third_party/yasm/BUILD.gn
+++ /dev/null
@@ -1,547 +0,0 @@
-# Copied from chromium third_party/yasm/, and modified for goma.
-#
-# 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.
-
-# The yasm build process creates a slew of small C subprograms that
-# dynamically generate files at various point in the build process.  This makes
-# the build integration moderately complex.
-#
-# There are three classes of dynamically generated files:
-#   1) C source files that should be included in the build (eg., lc3bid.c)
-#   2) C source files that are #included by static C sources (eg., license.c)
-#   3) Intermediate files that are used as input by other subprograms to
-#      further generate files in category #1 or #2.  (eg., version.mac)
-#
-# This structure is represented with the following targets:
-#   1) yasm -- Sources, flags for the main yasm executable. Also has most of
-#              of the actions and rules that invoke the subprograms.
-#   2) yasm_config -- General build configuration including setting a
-#              inputs listing the checked in version of files
-#              generated by manually running configure. These manually
-#              generated files are used by all binaries.
-#   3) yasm_utils -- Object files with memory management and hashing utilities
-#              shared between yasm and the genperf subprogram.
-#   4) genmacro, genmodule, etc. -- One executable target for each subprogram.
-#   5) generate_license, generate_module, etc. -- Actions that invoke programs
-#              built in #4 to generate .c files.
-#   6) compile_gperf, compile_re2c, etc. -- Actions that invoke programs that
-#              turn intermediate files into .c files.
-
-configs_to_delete = []
-configs_to_add = []
-
-if (current_toolchain == host_toolchain) {
-  # Various files referenced by multiple targets. yasm_gen_include_dir was moved
-  # from $target_gen_dir/include to avoid conflicts with x86insn_gas.c and
-  # x86insn_nasm.c. These files were previously generated during the build but
-  # are now shipped pre-generated by yasm.
-  yasm_gen_include_dir = "$target_gen_dir/gen_include"
-  config_makefile = "source/config/Makefile"
-  version_file = "version.mac"
-
-  import("//build/compiled_action.gni")
-
-  config("yasm_config") {
-    include_dirs = [
-      "source/config/$host_os",
-      "source/patched-yasm",
-    ]
-    defines = [ "HAVE_CONFIG_H" ]
-    if (is_posix) {
-      cflags = [ "-std=gnu99" ]
-    }
-  }
-
-  executable("genmacro") {
-    sources = [
-      "source/patched-yasm/tools/genmacro/genmacro.c",
-    ]
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-    ]
-    deps = [
-      "//build/config:exe_and_shlib_deps",
-
-      # Default manifest on Windows (a no-op elsewhere).
-      "//build/win:default_exe_manifest",
-    ]
-  }
-
-  executable("genmodule") {
-    sources = [
-      "source/patched-yasm/libyasm/genmodule.c",
-    ]
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-    ]
-    deps = [
-      "//build/config:exe_and_shlib_deps",
-
-      # Default manifest on Windows (a no-op elsewhere).
-      "//build/win:default_exe_manifest",
-    ]
-  }
-
-  executable("genperf") {
-    sources = [
-      "source/patched-yasm/tools/genperf/genperf.c",
-      "source/patched-yasm/tools/genperf/perfect.c",
-    ]
-
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-    ]
-
-    # Must be compatible with yasm_utils/yasm
-    configs -= configs_to_delete
-    configs += configs_to_add
-
-    deps = [
-      ":yasm_utils",
-      "//build/config:exe_and_shlib_deps",
-
-      # Default manifest on Windows (a no-op elsewhere).
-      "//build/win:default_exe_manifest",
-    ]
-  }
-
-  # Used by both yasm and genperf binaries.
-  static_library("yasm_utils") {
-    sources = [
-      "source/patched-yasm/libyasm/phash.c",
-      "source/patched-yasm/libyasm/xmalloc.c",
-      "source/patched-yasm/libyasm/xstrdup.c",
-    ]
-
-    configs -= [ "//build/config/compiler:goma_code" ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-    ]
-
-    # Must be compatible with yasm
-    configs -= configs_to_delete
-    configs += configs_to_add
-  }
-
-  executable("genstring") {
-    sources = [
-      "source/patched-yasm/genstring.c",
-    ]
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-    ]
-    deps = [
-      "//build/config:exe_and_shlib_deps",
-
-      # Default manifest on Windows (a no-op elsewhere).
-      "//build/win:default_exe_manifest",
-    ]
-  }
-
-  executable("genversion") {
-    sources = [
-      "source/patched-yasm/modules/preprocs/nasm/genversion.c",
-    ]
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-    ]
-    deps = [
-      "//build/config:exe_and_shlib_deps",
-
-      # Default manifest on Windows (a no-op elsewhere).
-      "//build/win:default_exe_manifest",
-    ]
-  }
-
-  config("re2c_warnings") {
-    # re2c is missing CLOSEVOP from one switch.
-    if (is_clang) {
-      cflags = [
-        # re2c is missing CLOSEVOP from one switch.
-        "-Wno-switch",
-
-        # re2c contains many static functions in headers (because it's
-        # a C library predating C99.)
-        "-Wno-unused-function",
-      ]
-    }
-  }
-
-  executable("re2c") {
-    sources = [
-      "source/patched-yasm/tools/re2c/actions.c",
-      "source/patched-yasm/tools/re2c/code.c",
-      "source/patched-yasm/tools/re2c/dfa.c",
-      "source/patched-yasm/tools/re2c/main.c",
-      "source/patched-yasm/tools/re2c/mbo_getopt.c",
-      "source/patched-yasm/tools/re2c/parser.c",
-      "source/patched-yasm/tools/re2c/scanner.c",
-      "source/patched-yasm/tools/re2c/substr.c",
-      "source/patched-yasm/tools/re2c/translate.c",
-    ]
-
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-
-      # Must be after no_goma_code for warning flags to be ordered
-      # correctly.
-      ":re2c_warnings",
-    ]
-    deps = [
-      "//build/config:exe_and_shlib_deps",
-
-      # Default manifest on Windows (a no-op elsewhere).
-      "//build/win:default_exe_manifest",
-    ]
-  }
-
-  config("yasm_warnings") {
-    if (is_clang) {
-      cflags = [
-        # reg3264type in x86expr.c is unused.
-        "-Wno-unused-local-typedef",
-      ]
-    }
-  }
-
-  executable("yasm") {
-    sources = [
-      "source/patched-yasm/frontends/yasm/yasm-options.c",
-      "source/patched-yasm/frontends/yasm/yasm.c",
-      "source/patched-yasm/libyasm/assocdat.c",
-      "source/patched-yasm/libyasm/bc-align.c",
-      "source/patched-yasm/libyasm/bc-data.c",
-      "source/patched-yasm/libyasm/bc-incbin.c",
-      "source/patched-yasm/libyasm/bc-org.c",
-      "source/patched-yasm/libyasm/bc-reserve.c",
-      "source/patched-yasm/libyasm/bitvect.c",
-      "source/patched-yasm/libyasm/bytecode.c",
-      "source/patched-yasm/libyasm/errwarn.c",
-      "source/patched-yasm/libyasm/expr.c",
-      "source/patched-yasm/libyasm/file.c",
-      "source/patched-yasm/libyasm/floatnum.c",
-      "source/patched-yasm/libyasm/hamt.c",
-      "source/patched-yasm/libyasm/insn.c",
-      "source/patched-yasm/libyasm/intnum.c",
-      "source/patched-yasm/libyasm/inttree.c",
-      "source/patched-yasm/libyasm/linemap.c",
-      "source/patched-yasm/libyasm/md5.c",
-      "source/patched-yasm/libyasm/mergesort.c",
-      "source/patched-yasm/libyasm/section.c",
-      "source/patched-yasm/libyasm/strcasecmp.c",
-      "source/patched-yasm/libyasm/strsep.c",
-      "source/patched-yasm/libyasm/symrec.c",
-      "source/patched-yasm/libyasm/valparam.c",
-      "source/patched-yasm/libyasm/value.c",
-      "source/patched-yasm/modules/arch/lc3b/lc3barch.c",
-      "source/patched-yasm/modules/arch/lc3b/lc3bbc.c",
-      "source/patched-yasm/modules/arch/x86/x86arch.c",
-      "source/patched-yasm/modules/arch/x86/x86bc.c",
-      "source/patched-yasm/modules/arch/x86/x86expr.c",
-      "source/patched-yasm/modules/arch/x86/x86id.c",
-      "source/patched-yasm/modules/dbgfmts/codeview/cv-dbgfmt.c",
-      "source/patched-yasm/modules/dbgfmts/codeview/cv-symline.c",
-      "source/patched-yasm/modules/dbgfmts/codeview/cv-type.c",
-      "source/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-aranges.c",
-      "source/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c",
-      "source/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-info.c",
-      "source/patched-yasm/modules/dbgfmts/dwarf2/dwarf2-line.c",
-      "source/patched-yasm/modules/dbgfmts/null/null-dbgfmt.c",
-      "source/patched-yasm/modules/dbgfmts/stabs/stabs-dbgfmt.c",
-      "source/patched-yasm/modules/listfmts/nasm/nasm-listfmt.c",
-      "source/patched-yasm/modules/objfmts/bin/bin-objfmt.c",
-      "source/patched-yasm/modules/objfmts/coff/coff-objfmt.c",
-      "source/patched-yasm/modules/objfmts/coff/win64-except.c",
-      "source/patched-yasm/modules/objfmts/dbg/dbg-objfmt.c",
-      "source/patched-yasm/modules/objfmts/elf/elf-objfmt.c",
-      "source/patched-yasm/modules/objfmts/elf/elf-x86-amd64.c",
-      "source/patched-yasm/modules/objfmts/elf/elf-x86-x32.c",
-      "source/patched-yasm/modules/objfmts/elf/elf-x86-x86.c",
-      "source/patched-yasm/modules/objfmts/elf/elf.c",
-      "source/patched-yasm/modules/objfmts/macho/macho-objfmt.c",
-      "source/patched-yasm/modules/objfmts/rdf/rdf-objfmt.c",
-      "source/patched-yasm/modules/objfmts/xdf/xdf-objfmt.c",
-      "source/patched-yasm/modules/parsers/gas/gas-parse-intel.c",
-      "source/patched-yasm/modules/parsers/gas/gas-parse.c",
-      "source/patched-yasm/modules/parsers/gas/gas-parser.c",
-      "source/patched-yasm/modules/parsers/nasm/nasm-parse.c",
-      "source/patched-yasm/modules/parsers/nasm/nasm-parser.c",
-      "source/patched-yasm/modules/preprocs/cpp/cpp-preproc.c",
-      "source/patched-yasm/modules/preprocs/gas/gas-eval.c",
-      "source/patched-yasm/modules/preprocs/gas/gas-preproc.c",
-      "source/patched-yasm/modules/preprocs/nasm/nasm-eval.c",
-      "source/patched-yasm/modules/preprocs/nasm/nasm-pp.c",
-      "source/patched-yasm/modules/preprocs/nasm/nasm-preproc.c",
-      "source/patched-yasm/modules/preprocs/nasm/nasmlib.c",
-      "source/patched-yasm/modules/preprocs/raw/raw-preproc.c",
-
-      # Files generated by compile_gperf
-      "$target_gen_dir/x86cpu.c",
-      "$target_gen_dir/x86regtmod.c",
-
-      # Files generated by compile_re2c
-      "$target_gen_dir/gas-token.c",
-      "$target_gen_dir/nasm-token.c",
-
-      # File generated by compile_re2c_lc3b
-      "$target_gen_dir/lc3bid.c",
-
-      # File generated by generate_module
-      "$target_gen_dir/module.c",
-    ]
-
-    configs -= [
-      "//build/config/compiler:goma_code",
-      "//build/config/sanitizers:default_sanitizer_flags",
-    ]
-    configs += [
-      ":yasm_config",
-      "//build/config/compiler:no_goma_code",
-      "//build/config/compiler:no_incompatible_pointer_warnings",
-
-      # Must be after no_goma_code for warning flags to be ordered
-      # correctly.
-      ":yasm_warnings",
-    ]
-
-    # Disable WPO for yasm: crbug.com/604808
-    configs -= configs_to_delete
-    configs += configs_to_add
-
-    # Yasm generates a bunch of .c files which its source file #include. These
-    # are placed in |yasm_gen_include_dir|.
-    include_dirs = [ yasm_gen_include_dir ]
-
-    # TODO: This should take most of the generated output as
-    # inputs.
-    deps = [
-      ":compile_gperf",
-      ":compile_gperf_for_include",
-      ":compile_nasm_macros",
-      ":compile_nasm_version",
-      ":compile_re2c",
-      ":compile_re2c_lc3b",
-      ":compile_win64_gas",
-      ":compile_win64_nasm",
-      ":generate_license",
-      ":generate_module",
-      ":generate_version",
-      ":yasm_utils",
-    ]
-  }
-
-  compiled_action_foreach("compile_gperf") {
-    tool = ":genperf"
-    sources = [
-      "source/patched-yasm/modules/arch/x86/x86cpu.gperf",
-      "source/patched-yasm/modules/arch/x86/x86regtmod.gperf",
-    ]
-
-    outputs = [
-      "$target_gen_dir/{{source_name_part}}.c",
-    ]
-    args = [
-      "{{source}}",
-      rebase_path(target_gen_dir, root_build_dir) + "/{{source_name_part}}.c",
-    ]
-  }
-
-  # This differs from |compile_gperf| in where it places it output files.
-  compiled_action_foreach("compile_gperf_for_include") {
-    tool = ":genperf"
-    sources = [
-      # Make sure the generated gperf files in $target_gen_dir are synced with
-      # the outputs for the related generate_*_insn actions in the
-      # generate_files target below.
-      #
-      # The output for these two are #included by
-      #   source/patched-yasm/modules/arch/x86/x86id.c
-      "source/patched-yasm/x86insn_gas.gperf",
-      "source/patched-yasm/x86insn_nasm.gperf",
-    ]
-
-    outputs = [
-      "$yasm_gen_include_dir/{{source_name_part}}.c",
-    ]
-    args = [
-      "{{source}}",
-      rebase_path(yasm_gen_include_dir, root_build_dir) +
-          "/{{source_name_part}}.c",
-    ]
-  }
-
-  template("compile_macro") {
-    compiled_action(target_name) {
-      tool = ":genmacro"
-
-      # Output #included by source/patched-yasm/frontends/yasm/yasm.c.
-      inputs = invoker.sources
-      outputs = invoker.outputs
-      args = [
-        rebase_path(outputs[0], root_build_dir),
-        invoker.macro_varname,
-        rebase_path(inputs[0], root_build_dir),
-      ]
-      if (defined(invoker.deps)) {
-        deps = invoker.deps
-      }
-    }
-  }
-
-  compile_macro("compile_nasm_macros") {
-    # Output #included by
-    #   source/patched-yasm/modules/preprocs/nasm/nasm-parser.c
-    sources = [
-      "source/patched-yasm/modules/parsers/nasm/nasm-std.mac",
-    ]
-    outputs = [
-      "$yasm_gen_include_dir/nasm-macros.c",
-    ]
-    macro_varname = "nasm_standard_mac"
-  }
-
-  compile_macro("compile_nasm_version") {
-    # Output #included by
-    #   source/patched-yasm/modules/preprocs/nasm/nasm-preproc.c
-    sources = [
-      "$target_gen_dir/$version_file",
-    ]
-    outputs = [
-      "$yasm_gen_include_dir/nasm-version.c",
-    ]
-    macro_varname = "nasm_version_mac"
-    deps = [
-      ":generate_version",
-    ]
-  }
-
-  compile_macro("compile_win64_gas") {
-    # Output #included by source/patched-yasm/frontends/yasm/yasm.c.
-    sources = [
-      "source/patched-yasm/modules/objfmts/coff/win64-gas.mac",
-    ]
-    outputs = [
-      "$yasm_gen_include_dir/win64-gas.c",
-    ]
-    macro_varname = "win64_gas_stdmac"
-  }
-
-  compile_macro("compile_win64_nasm") {
-    # Output #included by source/patched-yasm/frontends/yasm/yasm.c.
-    sources = [
-      "source/patched-yasm/modules/objfmts/coff/win64-nasm.mac",
-    ]
-    outputs = [
-      "$yasm_gen_include_dir/win64-nasm.c",
-    ]
-    macro_varname = "win64_nasm_stdmac"
-  }
-
-  compiled_action_foreach("compile_re2c") {
-    tool = ":re2c"
-    sources = [
-      "source/patched-yasm/modules/parsers/gas/gas-token.re",
-      "source/patched-yasm/modules/parsers/nasm/nasm-token.re",
-    ]
-    outputs = [
-      "$target_gen_dir/{{source_name_part}}.c",
-    ]
-    args = [
-      "-b",
-      "-o",
-      rebase_path(target_gen_dir, root_build_dir) + "/{{source_name_part}}.c",
-      "{{source}}",
-    ]
-  }
-
-  # This call doesn't fit into the re2c template above.
-  compiled_action("compile_re2c_lc3b") {
-    tool = ":re2c"
-    inputs = [
-      "source/patched-yasm/modules/arch/lc3b/lc3bid.re",
-    ]
-    outputs = [
-      "$target_gen_dir/lc3bid.c",
-    ]
-    args = [
-      "-s",
-      "-o",
-      rebase_path(outputs[0], root_build_dir),
-      rebase_path(inputs[0], root_build_dir),
-    ]
-  }
-
-  compiled_action("generate_license") {
-    tool = ":genstring"
-
-    # Output #included by source/patched-yasm/frontends/yasm/yasm.c.
-    inputs = [
-      "source/patched-yasm/COPYING",
-    ]
-    outputs = [
-      "$yasm_gen_include_dir/license.c",
-    ]
-    args = [
-      "license_msg",
-      rebase_path(outputs[0], root_build_dir),
-      rebase_path(inputs[0], root_build_dir),
-    ]
-  }
-
-  compiled_action("generate_module") {
-    tool = ":genmodule"
-    inputs = [
-      "source/patched-yasm/libyasm/module.in",
-      config_makefile,
-    ]
-    outputs = [
-      "$target_gen_dir/module.c",
-    ]
-    args = [
-      rebase_path(inputs[0], root_build_dir),
-      rebase_path(config_makefile, root_build_dir),
-      rebase_path(outputs[0], root_build_dir),
-    ]
-  }
-
-  compiled_action("generate_version") {
-    tool = ":genversion"
-    outputs = [
-      "$target_gen_dir/$version_file",
-    ]
-    args = [ rebase_path(outputs[0], root_build_dir) ]
-  }
-}
diff --git a/third_party/yasm/LICENSE b/third_party/yasm/LICENSE
deleted file mode 100644
index 254ada5..0000000
--- a/third_party/yasm/LICENSE
+++ /dev/null
@@ -1,69 +0,0 @@
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. Neither the name of the author nor the names of other contributors
-   may be used to endorse or promote products derived from this
-   software without specific prior written permission.
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
-NASM is now licensed under the 2-clause BSD license, also known as the
-simplified BSD license.
-    Copyright 1996-2009 the NASM Authors - All rights reserved.
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following
-    conditions are met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-      CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-      INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-      MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-      DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-      CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-      SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-      HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-      CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-      OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-      EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/yasm/README.goma b/third_party/yasm/README.goma
deleted file mode 100644
index 96b23c2..0000000
--- a/third_party/yasm/README.goma
+++ /dev/null
@@ -1,8 +0,0 @@
-Files under this directory is copied from chromium's src/third_party/yasm,
-and modified for goma.
-
-Modifications for goma:
-- *.gn and *.gni are changed to be used as goma's GN rule.
-  e.g. {,no_}goma_code instead of {,no_}_chromium_code
-       os == "win" instead of is_win.
-- removed unused configs.
diff --git a/third_party/yasm/run_yasm.py b/third_party/yasm/run_yasm.py
deleted file mode 100644
index 483a6dd..0000000
--- a/third_party/yasm/run_yasm.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copied from chromium third_party/yasm/.
-#
-# 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.
-
-"""A wrapper to run yasm.
-
-Its main job is to provide a Python wrapper for GN integration, and to write
-the makefile-style output yasm generates in stdout to a .d file for dependency
-management of .inc files.
-
-Run with:
-  python run_yasm.py <yasm_binary_path> <all other yasm args>
-
-Note that <all other yasm args> must include an explicit output file (-o). This
-script will append a ".d" to this and write the dependencies there. This script
-will add "-M" to cause yasm to write the deps to stdout, so you don't need to
-specify that.
-"""
-
-import argparse
-import sys
-import subprocess
-
-# Extract the output file name from the yasm command line so we can generate a
-# .d file with the same base name.
-parser = argparse.ArgumentParser()
-parser.add_argument("-o", dest="objfile")
-options, _ = parser.parse_known_args()
-
-objfile = options.objfile
-depfile = objfile + '.d'
-
-# Assemble.
-result_code = subprocess.call(sys.argv[1:])
-if result_code != 0:
-  sys.exit(result_code)
-
-# Now generate the .d file listing the dependencies. The -M option makes yasm
-# write the Makefile-style dependencies to stdout, but it seems that inhibits
-# generating any compiled output so we need to do this in a separate pass.
-# However, outputting deps seems faster than actually assembling, and yasm is
-# so fast anyway this is not a big deal.
-#
-# This guarantees proper dependency management for assembly files. Otherwise,
-# we would have to require people to manually specify the .inc files they
-# depend on in the build file, which will surely be wrong or out-of-date in
-# some cases.
-deps = subprocess.check_output(sys.argv[1:] + ['-M'])
-with open(depfile, "wb") as f:
-  f.write(deps)
diff --git a/third_party/yasm/source/config/Makefile b/third_party/yasm/source/config/Makefile
deleted file mode 100644
index 5a675e0..0000000
--- a/third_party/yasm/source/config/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copied from chromium third_party/yasm/source/config/Makefile.
-#
-# The YASM_MODULES line below is extracted from the Makefile generated by the
-# configure script.
-YASM_MODULES = arch_x86 arch_lc3b listfmt_nasm parser_gas parser_gnu \
-	parser_nasm parser_tasm preproc_nasm preproc_tasm preproc_raw \
-	preproc_cpp preproc_gas dbgfmt_cv8 dbgfmt_dwarf2 dbgfmt_null \
-	dbgfmt_stabs objfmt_dbg objfmt_bin objfmt_dosexe objfmt_elf \
-	objfmt_elf32 objfmt_elf64 objfmt_elfx32 objfmt_coff \
-	objfmt_macho objfmt_macho32 objfmt_macho64 objfmt_rdf \
-	objfmt_win32 objfmt_win64 objfmt_x64 objfmt_xdf
diff --git a/third_party/yasm/source/config/win/config.h b/third_party/yasm/source/config/win/config.h
deleted file mode 100644
index 12c081d..0000000
--- a/third_party/yasm/source/config/win/config.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Command name to run C preprocessor */
-#define CPP_PROG "cc -E"
-
-/* */
-/* #undef ENABLE_NLS */
-
-/* Define to 1 if you have the `abort' function. */
-#define HAVE_ABORT 1
-
-/* */
-/* #undef HAVE_CATGETS */
-
-/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the
-   CoreFoundation framework. */
-/* #undef HAVE_CFLOCALECOPYCURRENT */
-
-/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue i
-   the CoreFoundation framework. */
-/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
-
-/* Define if the GNU dcgettext() function is already present or preinstalled.
-   */
-#define HAVE_DCGETTEXT 1
-
-/* Define to 1 if you have the <direct.h> header file. */
-#define HAVE_DIRECT_H 1
-
-/* Define to 1 if you have the `ftruncate' function. */
-/* #undef HAVE_FTRUNCATE */
-
-/* Define to 1 if you have the `getcwd' function. */
-#define HAVE_GETCWD 1
-
-/* */
-#define HAVE_GETTEXT 1
-
-/* Define to 1 if you have the GNU C Library */
-/* #undef HAVE_GNU_C_LIBRARY */
-
-/* Define if you have the iconv() function and it works. */
-/* #undef HAVE_ICONV */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* */
-/* #undef HAVE_LC_MESSAGES */
-
-/* Define to 1 if you have the <libgen.h> header file. */
-/* #undef HAVE_LIBGEN_H */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mergesort' function. */
-/* #undef HAVE_MERGESORT */
-
-/* Define to 1 if you have the `popen' function. */
-/* #undef HAVE_POPEN */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* */
-/* #undef HAVE_STPCPY */
-
-/* Define to 1 if you have the `strcasecmp' function. */
-/* #undef HAVE_STRCASECMP */
-
-/* Define to 1 if you have the `strcmpi' function. */
-/* #undef HAVE_STRCMPI */
-
-/* Define to 1 if you have the `stricmp' function. */
-/* #undef HAVE_STRICMP */
-
-/* Define to 1 if you have the <strings.h> header file. */
-/* #undef HAVE_STRINGS_H */
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#define HAVE_STRNCASECMP 1
-
-/* Define to 1 if you have the `strsep' function. */
-/* #undef HAVE_STRSEP */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the `toascii' function. */
-#define HAVE_TOASCII 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-/* #undef HAVE_UNISTD_H */
-
-/* Define to 1 if you have the `vsnprintf' function. */
-#define HAVE_VSNPRINTF 1
-
-/* Define to 1 if you have the `_stricmp' function. */
-/* #undef HAVE__STRICMP */
-
-/* Name of package */
-#define PACKAGE "yasm"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "bug-yasm@tortall.net"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "yasm"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "yasm 1.3.0"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "yasm"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.3.0"
-
-/* Define to 1 if the C compiler supports function prototypes. */
-#define PROTOTYPES 1
-
-/* The size of `char', as computed by sizeof. */
-/* #undef SIZEOF_CHAR */
-
-/* The size of `int', as computed by sizeof. */
-/* #undef SIZEOF_INT */
-
-/* The size of `long', as computed by sizeof. */
-/* #undef SIZEOF_LONG */
-
-/* The size of `short', as computed by sizeof. */
-/* #undef SIZEOF_SHORT */
-
-/* The size of `void*', as computed by sizeof. */
-/* #undef SIZEOF_VOIDP */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.3.0"
-
-/* Define if using the dmalloc debugging malloc package */
-/* #undef WITH_DMALLOC */
-
-/* Define like PROTOTYPES; this can be used by system headers. */
-#define __PROTOTYPES 1
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
diff --git a/third_party/yasm/source/config/win/libyasm-stdint.h b/third_party/yasm/source/config/win/libyasm-stdint.h
deleted file mode 100644
index b9ce696..0000000
--- a/third_party/yasm/source/config/win/libyasm-stdint.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _YASM_LIBYASM_STDINT_H
-#define _YASM_LIBYASM_STDINT_H 1
-#ifndef _GENERATED_STDINT_H
-#define _GENERATED_STDINT_H "yasm 1.3.0"
-/* generated using gcc -std=gnu99 */
-#define _STDINT_HAVE_STDINT_H 1
-#include <stdint.h>
-#endif
-#endif
diff --git a/third_party/yasm/yasm_assemble.gni b/third_party/yasm/yasm_assemble.gni
deleted file mode 100644
index f164d07..0000000
--- a/third_party/yasm/yasm_assemble.gni
+++ /dev/null
@@ -1,198 +0,0 @@
-# Copied from chromium third_party/yasm/, and modified for goma.
-#
-# 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.
-
-# This provides the yasm_assemble() template which uses YASM to assemble
-# assembly files.
-#
-# Files to be assembled with YASM should have an extension of .asm.
-#
-# Parameters
-#
-#   yasm_flags (optional)
-#       [list of strings] Pass additional flags into YASM. These are appended
-#       to the command line. Note that the target machine type and system is
-#       already set up based on the current toolchain so you don't need to
-#       specify these things (see below).
-#
-#       Example: yasm_flags = [ "--force-strict" ]
-#
-#   include_dirs (optional)
-#       [list of dir names] List of additional include dirs. Note that the
-#       source root and the root generated file dir is always added, just like
-#       our C++ build sets up.
-#
-#       Example: include_dirs = [ "//some/other/path", target_gen_dir ]
-#
-#   defines (optional)
-#       [list of strings] List of defines, as with the native code defines.
-#
-#       Example: defines = [ "FOO", "BAR=1" ]
-#
-#   inputs, deps, visibility  (optional)
-#       These have the same meaning as in an action.
-#
-# Example
-#
-#   yasm_assemble("my_yasm_target") {
-#     sources = [
-#       "ultra_optimized_awesome.asm",
-#     ]
-#     include_dirs = [ "assembly_include" ]
-#   }
-
-if (os == "mac") {
-  if (cpu_arch == "x86") {
-    _yasm_flags = [
-      "-fmacho32",
-      "-m",
-      "x86",
-    ]
-  } else if (cpu_arch == "x64") {
-    _yasm_flags = [
-      "-fmacho64",
-      "-m",
-      "amd64",
-    ]
-  }
-} else if (is_posix) {
-  if (cpu_arch == "x86") {
-    _yasm_flags = [
-      "-felf32",
-      "-m",
-      "x86",
-    ]
-  } else if (cpu_arch == "x64") {
-    _yasm_flags = [
-      "-DPIC",
-      "-felf64",
-      "-m",
-      "amd64",
-    ]
-  }
-} else if (os == "win") {
-  if (cpu_arch == "x86") {
-    _yasm_flags = [
-      "-DPREFIX",
-      "-fwin32",
-      "-m",
-      "x86",
-    ]
-  } else if (cpu_arch == "x64") {
-    _yasm_flags = [
-      "-fwin64",
-      "-m",
-      "amd64",
-    ]
-  }
-}
-
-if (os == "win") {
-  asm_obj_extension = "obj"
-} else {
-  asm_obj_extension = "o"
-}
-
-template("yasm_assemble") {
-  assert(defined(invoker.sources), "Need sources defined for $target_name")
-
-  # Only depend on YASM on x86 systems. Force compilation of .asm files for
-  # ARM to fail.
-  assert(cpu_arch == "x86" || cpu_arch == "x64")
-
-  action_name = "${target_name}_action"
-  source_set_name = target_name
-
-  action_foreach(action_name) {
-    # Only the source set can depend on this.
-    visibility = [ ":$source_set_name" ]
-
-    script = "//third_party/yasm/run_yasm.py"
-    sources = invoker.sources
-
-    if (defined(invoker.inputs)) {
-      inputs = invoker.inputs
-    }
-
-    # Executable (first in the args). The binary might be in the root build dir
-    # (no cross-compiling) or in a toolchain-specific subdirectory of that
-    # (when cross-compiling).
-    yasm_label = "//third_party/yasm($host_toolchain)"
-    args = [ "./" +  # Force current dir.
-             rebase_path(get_label_info(yasm_label, "root_out_dir") + "/yasm",
-                         root_build_dir) ]
-
-    # Deps.
-    deps = [
-      yasm_label,
-    ]
-    if (defined(invoker.deps)) {
-      deps += invoker.deps
-    }
-
-    # Flags.
-    args += _yasm_flags
-    if (defined(invoker.yasm_flags)) {
-      args += invoker.yasm_flags
-    }
-
-    # User defined include dirs go first.
-    if (defined(invoker.include_dirs)) {
-      foreach(include, invoker.include_dirs) {
-        args += [ "-I" + rebase_path(include, root_build_dir) ]
-      }
-    }
-
-    # Default yasm include dirs. Make it match the native build (source root and
-    # root generated code directory).
-    # This goes to the end of include list.
-    args += [
-      "-I.",
-
-      # Using "//." will produce a relative path "../.." which looks better than
-      # "../../" which will result from using "//" as the base (although both
-      # work). This is because rebase_path will terminate the result in a
-      # slash if the input ends in a slash.
-      "-I" + rebase_path("//.", root_build_dir),
-      "-I" + rebase_path(root_gen_dir, root_build_dir),
-    ]
-
-    # Extra defines.
-    if (defined(invoker.defines)) {
-      foreach(def, invoker.defines) {
-        args += [ "-D$def" ]
-      }
-    }
-
-    # Output file.
-    outputs = [
-      "$target_out_dir/$source_set_name/{{source_name_part}}.o",
-    ]
-    args += [
-      "-o",
-      rebase_path(outputs[0], root_build_dir),
-      "{{source}}",
-    ]
-
-    # The wrapper script run_yasm will write the depfile to the same name as
-    # the output but with .d appended (like gcc will).
-    depfile = outputs[0] + ".d"
-  }
-
-  # Gather the .o files into a linkable thing. This doesn't actually link
-  # anything (a source set just compiles files to link later), but will pass
-  # the object files generated by the action up the dependency chain.
-  static_library(source_set_name) {
-    if (defined(invoker.visibility)) {
-      visibility = invoker.visibility
-    }
-
-    sources = get_target_outputs(":$action_name")
-
-    deps = [
-      ":$action_name",
-    ]
-  }
-}
diff --git a/tools/licenses.py b/tools/licenses.py
index 5c742d5..57afb5f 100755
--- a/tools/licenses.py
+++ b/tools/licenses.py
@@ -91,7 +91,7 @@
       continue
     license = FindLicense(args.third_party_dir, d)
     if not license:
-      raise Exception('license find not found in {}'.format(d))
+      raise Exception('license file not found in {}'.format(d))
     result = AddLicenseFile(result, d, license)
 
   with open(args.output_file, 'w') as f: