[go: nahoru, domu]

Revert "Reland "Reland "Reland "Add toolchains without PartitionAlloc-Everywhere for dump_syms et al""""

This reverts commit 4aceb04adee20a09c1e31760e8c6dafac2563d31.

Reason for revert: This appears to be causing build files to
fail to generate on "Centipede High End Upload Linux ASan"
giving the below error:

"""
ERROR Input to target not generated by a dependency.
The file:
  //out/Release/clang_x64_with_system_allocator/minidump_fuzzer
is listed as an input or source for the target:
  //third_party/breakpad:minidump_fuzzer
but no targets in the build generate that file.
"""

Original change's description:
> Reland "Reland "Reland "Add toolchains without PartitionAlloc-Everywhere for dump_syms et al"""
>
> This is a reland of commit 5e6def5bd2aa9cdbf69608a8edc32b5de696c091
> Which was a reland of commit 818e126f4350095dd0a54566ded107f0a5065f6f
> Which was a reland of commit 38c00784bc98a5dc885b06f5a0e738386c5f7df7
>
> When PartitionAlloc is linked into an executable, it takes over the
> system allocator (malloc, new, etc), which is called PartitionAlloc-
> Everywhere (or PA-E). When this occurs in dump_syms, we see that PA
> hits OOM and causes dump_syms to crash while generating the symbols
> for chrome. It's not at all clear why PA hits OOM but the system
> allocator does not, it occurs during construction of a std::string (on
> my machine anyway when I am running it in gdb, maybe elsewhere on bots).
> This happens on all platforms that we run dump_syms on as part of the
> official build: on linux and on mac, building for at least linux,
> android, chromeos, and mac. See also crbug.com/345514993.
>
> So we want to build dump_syms and other breakpad executables in a way
> that uses the system allocator. To do that we need to disable the
> use_partition_alloc_as_malloc GN variable. As this variable is global,
> we need a separate toolchain in order to disable it.
>
> We introduce a new toolchain with the suffix `_with_system_allocator`
> that can be used for this purpose. Initially we intended to use the
> Rust host build tools toolchain for this purpose, however we require
> careful naming to avoid toolchain collisions. For instance if building
> on a Linux x64 machine with an Other x64 target, we can have two
> toolchains:
> - default_toolchain: //build/toolchain/other:clang_x64
> - host_toolchain: //build/toolchain/other:clang_x64
>
> While these have different labels, it is the name at the end that is
> used as their output directory (this is hardcoded in GN). But they
> avoid colliding because the default toolchain is not placed in a
> subdirectory and uses the `root_build_dir`. However when we add another
> toolchain with them, they both get subdirs and collide:
> - for target: //build/toolchain/other:clang_x64_with_system_allocator
> - for host: //build/toolchain/linux:clang_x64_with_system_allocator
>
> Now both toolchains try to write to the clang_x64_with_system_allocator
> directory which causes errors. To avoid this, we actually make two
> toolchains per toolchain, one with a `host_` tag inside it.
> - target:  //build/toolchain/other:clang_x64_with_system_allocator
> - unused:  //build/toolchain/linux:clang_x64_with_system_allocator
> - unused:  //build/toolchain/other:clang_x64_host_with_system_allocator
> - host:    //build/toolchain/linux:clang_x64_host_with_system_allocator
>
> Then, when building for the host we choose the `host_` variety, which
> is specified in the `host_system_allocator_toolchain variable`. And
> when building for default target, we choose the non-`host_` one, which
> is specified in the `default_system_allocator_toolchain` variable.
>
> More clever strategies that try to avoid creating the unused toolchains
> above do not seem possible. Inside the toolchain-creating template,
> it is not clear how to determine which toolchain is being created, as
> the get_label_info() function on `target_name` does not produce
> anything that matches exactly with the string in `default_toolchain` or
> `host_toolchain`. We also tried using the current_cpu and current_os,
> however the `toolchain_args.current_os` is not actually set correctly in
> the default toolchain when targeting ChromeOS. The current_os variable
> is "chromeos" but inside the toolchain_args, it is "linux". So we just
> make extra toolchains (which can't be used or they'd make build errors)
> and we don't refer to them from the `host_system_allocator_toolchain`
> and `default_system_allocator_toolchain` variables, which makes them
> effectively inaccessible.
>
> In the process we learnt many things about how the breakpad executables
> are built. When you build them for the default toolchain, such as by
> building `//third_party/breakpad:dump_syms`, it redirects to the *host*
> toolchain on many platforms, but not on all platforms. This ends up
> putting a binary that may not work on the target machine in the
> `root_build_dir` which is highly unusual, but it is required by our
> testing scripts/infra.
>
> The key insight added here is that the toolchain that it should be
> built with is the platform from where the tests on the target will be
> *launched*. On Android, iOS, and ChromeOS, the tests are launched from
> the host machine and that's where the breakpad executables are run. We
> encode this explicitly in the breakpad GN file.
>
> One additional exception is that the breakpad tools do not build on
> Windows ARM, so when building on Windows x64 for Windows ARM, while
> the tests are launched from the ARM machine, we target the host x64
> machine still. This relies on the ARM machine being able to run the
> x64 binaries through emulation.
>
> There's no change here in how the breakpad binaries are built, but it
> is now more explicitly encoded and documented. What did change is that
> since we use a separate toolchain for building these tools, we also
> turn off component build in them. This allows us to replace the use
> of symlinks with copying (or hardlinking) the binaries from the
> toolchain's root directory up to the root_build_dir. This enables
> support for building these tools in the default_toolchain on Windows,
> something which was not possible before.
>
> Additional fixes from the original CL:
>
> MSAN is disabled in the toolchain with the system allocator as we only
> support MSAN in the default toolchain. If another toolchain has MSAN
> enabled it will try to also generate the MSAN instrumented libraries
> in the default toolchain's directory and they collide. This is similar
> to the rust host build tools toolchain, but there we disable all
> sanitizers. For the system allocator toolchain, we disable MSAN but
> retain the ability to build these tools with ASAN or UBSAN if needed.
>
> Angle's GN generation is fixed by not setting the PA variable directly
> from the toolchain. We add a variable in toolchain.gni that is always
> present, and set that. Then in the PA gni files, we check for that
> variable before enabling PA-Everywhere (and BRP, etc).
>
> Devtools standalone overrides BUILDCONFIG.gn but was not re-defining
> the TESTONLY_AND_VISIBILITY variable, so this is done in
> https://chrome-internal-review.googlesource.com/c/devtools/devtools-internal/+/7412037
>
> iOS official internal builders are now using the path to the
> root_build_dir for its dump_syms exe path from
> https://chrome-internal-review.googlesource.com/c/chrome/ios_internal/+/7411376
> and it expects the executable to be for the host. A TODO is added
> in the breakpad BUILD.gn file regarding cross-compiling for a
> different mac machine architecture that will upload/launch tests to
> the iOS device.
>
> Mac and Windows internal official builders are fixed by having the
> symupload tool depended on and built for the default toolchain so that
> it's present in the root_build_dir, but making this binary always
> redirect through the host_system_allocator_toolchain. The symupload
> binary is only run on official builders, it's not part of test
> failure reporting like dump_syms.
>
> Clank orderfile generator had a GN error due to PA-E being off but
> BRP being enabled. This is resolved by the fix for Angle, by turning
> off all PA-E and BRP related stuff when the toolchain turns off PA-E.
> See https://crbug.com/347976629.
>
> Further additional fixes from the original CL:
>
> The minidump_fuzzer is added to the default toolchain, redirecting to
> the test-launcher toolchain.
>
> The windows host system-allocator toolchain is forced to use the host
> cpu, rather than using the the x86 cpu when cross-compiling.
>
> The Linux-to-Windows cross build avoids putting a `.exe` suffix on
> executables built for the host system-allocator toolchain as targets
> for Linux do not have them, and then GN can't find the requested
> target.
>
> Even more additional fixes:
>
> The previous attempt to get the host system-allocator toolchain to use
> the host cpu on Windows was incomplete. It only updated the non-clang
> toolchain, and it missed changing the environment to point to the host
> cpu's sdk. This is now done correctly.
>
> Removed the redundant output_name field in the windows symupload
> executable target, as the executable target is now named symupload, and
> not symupload_win.
>
> Explicitly add a `$host_toolchain/symupload` alias on Mac ARM so that
> the recipes which explicitly build and run that path will work when
> this lands. Once it reaches stable we can remove those explicit paths
> from the recipes.
>
> Bug: 345514993, b/342251590, 347976629, 349268750
> Change-Id: I35aca8e8d5224aa27bceebb4c815a702a2f50516
> Cq-Include-Trybots: luci.chromium.try:linux-official,android-official,win-official,mac-official
> Cq-Include-Trybots: luci.chromium.try:linux_chromium_msan_rel_ng
> Cq-Include-Trybots: luci.chromium.try:linux_chromium_asan_rel_ng
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5659276
> Reviewed-by: Hans Wennborg <hans@chromium.org>
> Commit-Queue: danakj <danakj@chromium.org>
> Reviewed-by: Mark Mentovai <mark@chromium.org>
> Reviewed-by: Avi Drissman <avi@chromium.org>
> Owners-Override: danakj <danakj@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1322382}

Bug: 345514993, b/342251590, 347976629, 349268750
Change-Id: I66b9a3fb22627681ae41893a0fc0349ea5ea1a1f
Cq-Include-Trybots: luci.chromium.try:linux-official,android-official,win-official,mac-official
Cq-Include-Trybots: luci.chromium.try:linux_chromium_msan_rel_ng
Cq-Include-Trybots: luci.chromium.try:linux_chromium_asan_rel_ng
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5673027
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Michael Wilson <mjwilson@chromium.org>
Commit-Queue: Michael Wilson <mjwilson@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1322410}
diff --git a/BUILD.gn b/BUILD.gn
index ff9f9c3a2..d08e389 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -603,10 +603,10 @@
         "//mojo:mojo_perftests",
         "//services/service_manager/public/cpp",
         "//testing/gmock:gmock_main",
-        "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)",
-        "//third_party/breakpad:microdump_stackwalk($host_system_allocator_toolchain)",
-        "//third_party/breakpad:minidump_dump($host_system_allocator_toolchain)",
-        "//third_party/breakpad:minidump_stackwalk($host_system_allocator_toolchain)",
+        "//third_party/breakpad:dump_syms($host_toolchain)",
+        "//third_party/breakpad:microdump_stackwalk($host_toolchain)",
+        "//third_party/breakpad:minidump_dump($host_toolchain)",
+        "//third_party/breakpad:minidump_stackwalk($host_toolchain)",
       ]
     }
 
@@ -628,7 +628,7 @@
 
     if (is_mac) {
       deps += [
-        "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)",
+        "//third_party/breakpad:dump_syms",
 
         # The following are accessibility API tools.
         "//tools/accessibility/inspect:ax_dump_events",
@@ -672,29 +672,7 @@
           host_os == "win") {
         deps += [ "//chrome/test/mini_installer:mini_installer_tests" ]
       }
-    }
-
-    if (!is_fuchsia) {
-      # The official builders use this binary from the default toolchain's
-      # output directory after building in order to upload the symbols of that
-      # binary. They build the binary like `ninja symupload` which requires the
-      # target to be a dependency in the default_toolchain from `gn_all` for the
-      # name to resolve.
-      deps += [ "//third_party/breakpad:symupload" ]
-    }
-    if (is_mac) {
-      # TODO(crbug.com/349268750): This alias exists because the official Mac
-      # arm64 builders (which cross-build the x64 binaries) use the hardcoded
-      # path of the `$host_toolchain/symupload` to build and run the symupload
-      # binary. And the same recipes are used on all branches!! So we would break
-      # the stable branch builders by changing the recipe to build and run the
-      # binary from the root_build_dir.
-      #
-      # Once this code is in stable, we can land the following CLs to change how
-      # symupload is built and run on Mac arm64 official builders, and then this
-      # alias can be removed.
-      # Build: https://chrome-internal-review.googlesource.com/c/chrome/src-internal/+/7430844
-      # Run: https://chrome-internal-review.googlesource.com/c/chrome/tools/release/scripts/+/7430843
+    } else if (!is_android && !is_ios && !is_fuchsia) {
       deps += [ "//third_party/breakpad:symupload($host_toolchain)" ]
     }
 
@@ -1000,7 +978,7 @@
       "//net:net_unittests",
       "//printing:printing_unittests",
       "//sql:sql_unittests",
-      "//third_party/breakpad:symupload",
+      "//third_party/breakpad:symupload($host_toolchain)",
       "//ui/base:ui_base_unittests",
       "//ui/gfx:gfx_unittests",
       "//ui/touch_selection:ui_touch_selection_unittests",
@@ -1029,7 +1007,7 @@
       "//sandbox/linux:chrome_sandbox",
       "//sandbox/linux:sandbox_linux_unittests",
       "//services/screen_ai:screen_ai_ocr_perf_test",
-      "//third_party/breakpad:minidump_stackwalk($host_system_allocator_toolchain)",
+      "//third_party/breakpad:minidump_stackwalk($host_toolchain)",
       "//third_party/dawn/src/dawn/tests:dawn_end2end_tests",
       "//third_party/dawn/src/dawn/tests:dawn_unittests",
       "//ui/ozone:ozone_integration_tests",
@@ -1203,40 +1181,28 @@
     if (is_android) {
       data_deps += [
         "//third_party/breakpad:breakpad_unittests",
-        "//tools/android/forwarder2",
-
-        # Using the target toolchain for this tool, as it's run during tests not
-        # during the build. This places a symlink in the root_build_dir for
-        # scrips to use.
         "//third_party/breakpad:dump_syms",
         "//third_party/breakpad:microdump_stackwalk",
         "//third_party/breakpad:minidump_dump",
         "//third_party/breakpad:minidump_stackwalk",
         "//third_party/breakpad:symupload",
+        "//tools/android/forwarder2",
       ]
     } else {
       data_deps += [ "//content/web_test:web_test_common_mojom_js_data_deps" ]
     }
 
     if (!is_win && !is_android) {
-      # Using the default toolchain for this tool, as it's run during tests not
-      # during the build. This places a symlink in the root_build_dir for scrips
-      # to use.
-      data_deps += [ "//third_party/breakpad:minidump_stackwalk" ]
+      data_deps +=
+          [ "//third_party/breakpad:minidump_stackwalk($host_toolchain)" ]
     }
 
     if (is_mac) {
-      # Using the default toolchain for this tool, as it's run during tests not
-      # during the build, and on Mac we support cross-building from a different
-      # architecture.
-      data_deps += [ "//third_party/breakpad:dump_syms" ]
+      data_deps += [ "//third_party/breakpad:dump_syms($host_toolchain)" ]
     }
 
     if (is_linux || is_chromeos) {
-      # Using the default toolchain for this tool, as it's run during tests not
-      # during the build. This places a symlink in the root_build_dir for scrips
-      # to use.
-      data_deps += [ "//third_party/breakpad:dump_syms" ]
+      data_deps += [ "//third_party/breakpad:dump_syms($host_toolchain)" ]
     }
 
     if (is_fuchsia) {
@@ -1700,7 +1666,8 @@
     }
 
     if (!is_win) {
-      data_deps += [ "//third_party/breakpad:minidump_stackwalk($host_system_allocator_toolchain)" ]
+      data_deps +=
+          [ "//third_party/breakpad:minidump_stackwalk($host_toolchain)" ]
     }
   }
 
diff --git a/base/allocator/partition_allocator/partition_alloc.gni b/base/allocator/partition_allocator/partition_alloc.gni
index a74c637..a4eccae4 100644
--- a/base/allocator/partition_allocator/partition_alloc.gni
+++ b/base/allocator/partition_allocator/partition_alloc.gni
@@ -255,9 +255,7 @@
 # Do not clear the following, as they can function outside of PartitionAlloc
 # - has_64_bit_pointers
 # - has_memory_tagging
-if (!use_partition_alloc ||
-    (defined(toolchain_allows_use_partition_alloc_as_malloc) &&
-     !toolchain_allows_use_partition_alloc_as_malloc)) {
+if (!use_partition_alloc) {
   use_partition_alloc_as_malloc = false
   glue_core_pools = false
   enable_backup_ref_ptr_support = false
@@ -270,7 +268,6 @@
   enable_dangling_raw_ptr_feature_flag = false
   enable_pointer_subtraction_check = false
   backup_ref_ptr_poison_oob_ptr = false
-  backup_ref_ptr_extra_oob_checks = false
   enable_backup_ref_ptr_instance_tracer = false
   use_starscan = false
   use_full_mte = false
diff --git a/build/config/android/create_unwind_table.gni b/build/config/android/create_unwind_table.gni
index 59cb024..92b7427 100644
--- a/build/config/android/create_unwind_table.gni
+++ b/build/config/android/create_unwind_table.gni
@@ -6,8 +6,7 @@
 
 unwind_table_asset_v2_filename = "unwind_cfi_32_v2"
 
-_dump_syms_target =
-    "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)"
+_dump_syms_target = "//third_party/breakpad:dump_syms($host_toolchain)"
 _dump_syms = get_label_info(_dump_syms_target, "root_out_dir") + "/dump_syms"
 _readobj_path = "$clang_base_path/bin/llvm-readobj"
 
diff --git a/build/config/android/extract_unwind_tables.gni b/build/config/android/extract_unwind_tables.gni
index 6518a2d..d4daa6a 100644
--- a/build/config/android/extract_unwind_tables.gni
+++ b/build/config/android/extract_unwind_tables.gni
@@ -6,8 +6,7 @@
 
 unwind_table_asset_v1_filename = "unwind_cfi_32"
 
-_dump_syms_target =
-    "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)"
+_dump_syms_target = "//third_party/breakpad:dump_syms($host_toolchain)"
 _dump_syms = get_label_info(_dump_syms_target, "root_out_dir") + "/dump_syms"
 
 template("unwind_table_v1") {
diff --git a/build/linux/extract_symbols.gni b/build/linux/extract_symbols.gni
index 26426c8..8fef131 100644
--- a/build/linux/extract_symbols.gni
+++ b/build/linux/extract_symbols.gni
@@ -18,8 +18,7 @@
                            "testonly",
                          ])
   action("${target_name}") {
-    dump_syms_label =
-        "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)"
+    dump_syms_label = "//third_party/breakpad:dump_syms($host_toolchain)"
     dump_syms_binary =
         get_label_info(dump_syms_label, "root_out_dir") + "/" + "dump_syms"
 
diff --git a/build/toolchain/apple/toolchain.gni b/build/toolchain/apple/toolchain.gni
index acd5a59f..9e138aa 100644
--- a/build/toolchain/apple/toolchain.gni
+++ b/build/toolchain/apple/toolchain.gni
@@ -792,68 +792,6 @@
   }
 }
 
-# Make an additional toolchain which is used for making tools that are run
-# on the host machine as part of the build process (such as proc macros
-# and Cargo build scripts). This toolchain uses the prebuilt stdlib that
-# comes with the compiler, so it doesn't have to wait for the stdlib to be
-# built before building other stuff. And this ensures its proc macro
-# outputs have the right ABI to be loaded by the compiler, and it can be
-# used to compile build scripts that are part of the stdlib that is built
-# for the default toolchain.
-template("apple_rust_host_build_tools_toolchain") {
-  single_apple_toolchain(target_name) {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker,
-                           "*",
-                           TESTONLY_AND_VISIBILITY + [ "toolchain_args" ])
-    toolchain_args = {
-      # Populate toolchain args from the invoker.
-      forward_variables_from(invoker.toolchain_args, "*")
-      toolchain_for_rust_host_build_tools = true
-
-      # The host build tools are static release builds to make the Chromium
-      # build faster. They do not need PGO etc, so no official builds.
-      is_debug = false
-      is_component_build = false
-      is_official_build = false
-      use_clang_coverage = false
-      use_sanitizer_coverage = false
-      generate_linker_map = false
-      use_thin_lto = false
-    }
-  }
-}
-
-# If PartitionAlloc is part of the build (even as a transitive dependency), then
-# it replaces the system allocator. If this toolchain is used, that will be
-# overridden and the system allocator will be used regardless. This is important
-# in some third-party binaries outside of Chrome.
-template("apple_system_allocator_toolchain") {
-  single_apple_toolchain(target_name) {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker,
-                           "*",
-                           TESTONLY_AND_VISIBILITY + [ "toolchain_args" ])
-    toolchain_args = {
-      # Populate toolchain args from the invoker.
-      forward_variables_from(invoker.toolchain_args, "*")
-      toolchain_allows_use_partition_alloc_as_malloc = false
-
-      # Disable component build so that we can copy the exes to the
-      # root_build_dir and support the default_toolchain redirection on Windows.
-      # See also the comment in //build/symlink.gni.
-      is_component_build = false
-
-      # Only one toolchain can be configured with MSAN support with our current
-      # GN setup, or they all try to make the instrumented libraries and
-      # collide.
-      is_msan = false
-    }
-  }
-}
-
 # Makes an Apple toolchain for the target, and an equivalent toolchain with the
 # prebuilt Rust stdlib for building proc macros (and other for-build-use
 # artifacts).
@@ -861,28 +799,51 @@
   single_apple_toolchain(target_name) {
     assert(defined(invoker.toolchain_args),
            "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+    forward_variables_from(invoker,
+                           "*",
+                           [
+                             "visibility",
+                             "test_only",
+                           ])
 
     # No need to forward visibility and test_only as they apply to targets not
     # toolchains, but presubmit checks require that we explicitly exclude them
   }
 
-  apple_rust_host_build_tools_toolchain(
-      "${target_name}_for_rust_host_build_tools") {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
-  }
+  if (enable_rust && current_toolchain == default_toolchain) {
+    # Make an additional toolchain which is used for making tools that are run
+    # on the host machine as part of the build process (such as proc macros
+    # and Cargo build scripts). This toolchain uses the prebuilt stdlib that
+    # comes with the compiler, so it doesn't have to wait for the stdlib to be
+    # built before building other stuff. And this ensures its proc macro
+    # outputs have the right ABI to be loaded by the compiler, and it can be
+    # used to compile build scripts that are part of the stdlib that is built
+    # for the default toolchain.
+    single_apple_toolchain("${target_name}_for_rust_host_build_tools") {
+      assert(defined(invoker.toolchain_args),
+             "Toolchains must declare toolchain_args")
+      forward_variables_from(invoker,
+                             "*",
+                             [
+                               "toolchain_args",
+                               "visibility",
+                               "test_only",
+                             ])
+      toolchain_args = {
+        # Populate toolchain args from the invoker.
+        forward_variables_from(invoker.toolchain_args, "*")
+        toolchain_for_rust_host_build_tools = true
 
-  apple_system_allocator_toolchain(
-      "${target_name}_host_with_system_allocator") {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
-  }
-  apple_system_allocator_toolchain("${target_name}_with_system_allocator") {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+        # The host build tools are static release builds to make the Chromium
+        # build faster. They do not need PGO etc, so no official builds.
+        is_debug = false
+        is_component_build = false
+        is_official_build = false
+        use_clang_coverage = false
+        use_sanitizer_coverage = false
+        generate_linker_map = false
+        use_thin_lto = false
+      }
+    }
   }
 }
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index 1dc27be..09f1f39 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -141,10 +141,8 @@
            "toolchain_args must specify a current_os")
 
     # use_reclient is default to use_remoteexec
-    if (!defined(invoker_toolchain_args.use_reclient) &&
-        defined(invoker_toolchain_args.use_remoteexec)) {
-      invoker_toolchain_args.use_reclient =
-          invoker_toolchain_args.use_remoteexec
+    if (!defined(invoker_toolchain_args.use_reclient) && defined(invoker_toolchain_args.use_remoteexec)) {
+      invoker_toolchain_args.use_reclient = invoker_toolchain_args.use_remoteexec
     }
 
     # When invoking this toolchain not as the default one, these args will be
@@ -798,72 +796,6 @@
   }
 }
 
-# Make an additional toolchain which is used for making tools that are run
-# on the host machine as part of the build process (such as proc macros
-# and Cargo build scripts). This toolchain uses the prebuilt stdlib that
-# comes with the compiler, so it doesn't have to wait for the stdlib to be
-# built before building other stuff. And this ensures its proc macro
-# outputs have the right ABI to be loaded by the compiler, and it can be
-# used to compile build scripts that are part of the stdlib that is built
-# for the default toolchain.
-template("gcc_rust_host_build_tools_toolchain") {
-  single_gcc_toolchain(target_name) {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker,
-                           "*",
-                           TESTONLY_AND_VISIBILITY + [ "toolchain_args" ])
-    toolchain_args = {
-      # Populate toolchain args from the invoker.
-      forward_variables_from(invoker.toolchain_args, "*")
-      toolchain_for_rust_host_build_tools = true
-
-      # The host build tools are static release builds to make the Chromium
-      # build faster.
-      is_debug = false
-      is_component_build = false
-      is_official_build = false
-      use_clang_coverage = false
-      use_sanitizer_coverage = false
-      generate_linker_map = false
-      use_thin_lto = false
-    }
-
-    # When cross-compiling we don't want to use the target platform's file
-    # extensions.
-    shlib_extension = host_shlib_extension
-  }
-}
-
-# If PartitionAlloc is part of the build (even as a transitive dependency), then
-# it replaces the system allocator. If this toolchain is used, that will be
-# overridden and the system allocator will be used regardless. This is important
-# in some third-party binaries outside of Chrome.
-template("gcc_system_allocator_toolchain") {
-  single_gcc_toolchain(target_name) {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker,
-                           "*",
-                           TESTONLY_AND_VISIBILITY + [ "toolchain_args" ])
-    toolchain_args = {
-      # Populate toolchain args from the invoker.
-      forward_variables_from(invoker.toolchain_args, "*")
-      toolchain_allows_use_partition_alloc_as_malloc = false
-
-      # Disable component build so that we can copy the exes to the
-      # root_build_dir and support the default_toolchain redirection on Windows.
-      # See also the comment in //build/symlink.gni.
-      is_component_build = false
-
-      # Only one toolchain can be configured with MSAN support with our current
-      # GN setup, or they all try to make the instrumented libraries and
-      # collide.
-      is_msan = false
-    }
-  }
-}
-
 # Makes a GCC toolchain for the target, and an equivalent toolchain with the
 # prebuilt Rust stdlib for building proc macros (and other for-build-use
 # artifacts).
@@ -871,28 +803,56 @@
   single_gcc_toolchain(target_name) {
     assert(defined(invoker.toolchain_args),
            "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+    forward_variables_from(invoker,
+                           "*",
+                           [
+                             "visibility",
+                             "test_only",
+                           ])
 
     # No need to forward visibility and test_only as they apply to targets not
     # toolchains, but presubmit checks require that we explicitly exclude them
   }
 
-  gcc_rust_host_build_tools_toolchain(
-      "${target_name}_for_rust_host_build_tools") {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
-  }
+  if (enable_rust && current_toolchain == default_toolchain) {
+    # Make an additional toolchain which is used for making tools that are run
+    # on the host machine as part of the build process (such as proc macros
+    # and Cargo build scripts). This toolchain uses the prebuilt stdlib that
+    # comes with the compiler, so it doesn't have to wait for the stdlib to be
+    # built before building other stuff. And this ensures its proc macro
+    # outputs have the right ABI to be loaded by the compiler, and it can be
+    # used to compile build scripts that are part of the stdlib that is built
+    # for the default toolchain.
+    single_gcc_toolchain("${target_name}_for_rust_host_build_tools") {
+      assert(defined(invoker.toolchain_args),
+             "Toolchains must declare toolchain_args")
+      forward_variables_from(invoker,
+                             "*",
+                             [
+                               "toolchain_args",
+                               "visibility",
+                               "test_only",
+                             ])
+      toolchain_args = {
+        # Populate toolchain args from the invoker.
+        forward_variables_from(invoker.toolchain_args, "*")
+        toolchain_for_rust_host_build_tools = true
 
-  gcc_system_allocator_toolchain("${target_name}_host_with_system_allocator") {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
-  }
-  gcc_system_allocator_toolchain("${target_name}_with_system_allocator") {
-    assert(defined(invoker.toolchain_args),
-           "Toolchains must declare toolchain_args")
-    forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+        # The host build tools are static release builds to make the Chromium
+        # build faster.
+        is_debug = false
+        is_component_build = false
+        is_official_build = false
+        use_clang_coverage = false
+        use_sanitizer_coverage = false
+        generate_linker_map = false
+        use_thin_lto = false
+      }
+
+      # When cross-compiling we don't want to use the target platform's file
+      # extensions.
+      shlib_extension = host_shlib_extension
+    }
   }
 }
 
diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni
index 1637a34c..14aa5f7 100644
--- a/build/toolchain/toolchain.gni
+++ b/build/toolchain/toolchain.gni
@@ -30,10 +30,6 @@
   # consumed during the build process. That includes proc macros and Cargo build
   # scripts.
   toolchain_for_rust_host_build_tools = false
-
-  # If false, the toolchain overrides `use_partition_alloc_as_malloc` in
-  # PartitionAlloc, to allow use of the system allocator.
-  toolchain_allows_use_partition_alloc_as_malloc = true
 }
 
 if (generate_linker_map) {
@@ -120,15 +116,3 @@
 is_a_target_toolchain =
     (current_toolchain != host_toolchain ||
      default_toolchain == host_toolchain) && current_os == target_os
-
-# A toolchain for building tools that run on the host machine and need to use
-# the system allocator. This toolchain does not use PartitionAlloc-Everywhere by
-# design. We use a name with `_host` injected into it to avoid colliding with
-# toolchains of the same name (but different path) between different OSes.
-host_system_allocator_toolchain = "${host_toolchain}_host_with_system_allocator"
-
-# A toolchain for building tools that run on the default target machine and need
-# to use the system allocator. This toolchain does not use
-# PartitionAlloc-Everywhere by design.
-default_system_allocator_toolchain =
-    "${default_toolchain}_with_system_allocator"
diff --git a/build/toolchain/win/toolchain.gni b/build/toolchain/win/toolchain.gni
index 3d7ab88..c2d8d3a 100644
--- a/build/toolchain/win/toolchain.gni
+++ b/build/toolchain/win/toolchain.gni
@@ -589,71 +589,36 @@
   }
 }
 
-# Make an additional toolchain which is used for making tools that are run
-# on the host machine as part of the build process (such as proc macros
-# and Cargo build scripts). This toolchain uses the prebuilt stdlib that
-# comes with the compiler, so it doesn't have to wait for the stdlib to be
-# built before building other stuff. And this ensures its proc macro
-# outputs have the right ABI to be loaded by the compiler, and it can be
-# used to compile build scripts that are part of the stdlib that is built
-# for the default toolchain.
 template("msvc_rust_host_build_tools_toolchain") {
-  msvc_toolchain(target_name) {
-    assert(defined(invoker.toolchain_args))
-    forward_variables_from(invoker,
-                           "*",
-                           [
-                             "toolchain_args",
-                             "visibility",
-                             "testonly",
-                           ])
-    toolchain_args = {
-      # Populate toolchain args from the invoker.
-      forward_variables_from(invoker.toolchain_args, "*")
-      toolchain_for_rust_host_build_tools = true
+  assert(defined(invoker.toolchain_args))
+  if (enable_rust) {
+    msvc_toolchain("${target_name}_for_rust_host_build_tools") {
+      forward_variables_from(invoker,
+                             "*",
+                             [
+                               "toolchain_args",
+                               "visibility",
+                               "testonly",
+                             ])
+      toolchain_args = {
+        # Populate toolchain args from the invoker.
+        forward_variables_from(invoker.toolchain_args, "*")
+        toolchain_for_rust_host_build_tools = true
 
-      # The host build tools are static release builds to make the Chromium
-      # build faster. They do not need PGO etc, so no official builds.
-      is_debug = false
-      is_component_build = false
-      is_official_build = false
-      use_clang_coverage = false
-      use_sanitizer_coverage = false
-      generate_linker_map = false
-      use_thin_lto = false
+        # The host build tools are static release builds to make the Chromium
+        # build faster. They do not need PGO etc, so no official builds.
+        is_debug = false
+        is_component_build = false
+        is_official_build = false
+        use_clang_coverage = false
+        use_sanitizer_coverage = false
+        generate_linker_map = false
+        use_thin_lto = false
+      }
     }
-  }
-}
-
-# If PartitionAlloc is part of the build (even as a transitive dependency), then
-# it replaces the system allocator. If this toolchain is used, that will be
-# overridden and the system allocator will be used regardless. This is important
-# in some third-party binaries outside of Chrome.
-template("msvc_system_allocator_toolchain") {
-  msvc_toolchain(target_name) {
-    assert(defined(invoker.toolchain_args))
-    forward_variables_from(invoker,
-                           "*",
-                           [
-                             "toolchain_args",
-                             "visibility",
-                             "testonly",
-                           ])
-    toolchain_args = {
-      # Populate toolchain args from the invoker.
-      forward_variables_from(invoker.toolchain_args, "*")
-      toolchain_allows_use_partition_alloc_as_malloc = false
-
-      # Disable component build so that we can copy the exes to the
-      # root_build_dir and support the default_toolchain redirection on Windows.
-      # See also the comment in //build/symlink.gni.
-      is_component_build = false
-
-      # Only one toolchain can be configured with MSAN support with our current
-      # GN setup, or they all try to make the instrumented libraries and
-      # collide.
-      is_msan = false
-    }
+  } else {
+    not_needed(invoker, "*")
+    not_needed([ "target_name" ])
   }
 }
 
@@ -663,12 +628,12 @@
   # //build/config/BUILDCONFIG.gn). But the prebuilt stdlib does not
   # exist for Windows x86 and it's exceedingly difficult to get it
   # built from a single build_rust.py invocation. So we just don't follow
-  # along in the `build_tools_toolchain` toolchains, and always use the host
-  # cpu type (which will be x64 in that case). Things built with these
-  # toolchains are never built for the target_cpu anyhow, so the optimization
-  # there does not benefit them.
+  # along in the `msvc_rust_host_build_tools_toolchain` toolchains, and
+  # always use the host cpu type (which will be x64 in that case). Things
+  # built with these toolchains are never built for the target_cpu anyhow,
+  # so the optimization there does not benefit them.
   #
-  # Thus, in build_tools_toolchain, for the host machine:
+  # Thus, in msvc_rust_host_build_tools_toolchain:
   # * Use `rust_host_toolchain_arch` instead of `toolchain_arch`.
   # * Use `rust_host_win_toolchain_data` instead of `win_toolchain_data`.
 
@@ -687,7 +652,7 @@
     error("Unsupported toolchain_arch, add it to win_toolchain_data.gni")
   }
 
-  # The toolchain data for `build_tools_toolchain` for the host machine.
+  # The toolchain data for `msvc_rust_host_build_tools_toolchain()`.
   if (rust_host_toolchain_arch == "x86") {
     rust_host_win_toolchain_data = win_toolchain_data_x86
   } else if (rust_host_toolchain_arch == "x64") {
@@ -722,38 +687,7 @@
         current_cpu = toolchain_arch
       }
     }
-    msvc_system_allocator_toolchain(
-        cl_toolchain_prefix + target_name + "_host_with_system_allocator") {
-      environment = "environment." + rust_host_toolchain_arch
-      cl = "\"${rust_host_win_toolchain_data.vc_bin_dir}/cl.exe\""
-
-      toolchain_args = {
-        if (defined(invoker.toolchain_args)) {
-          forward_variables_from(invoker.toolchain_args, "*")
-        }
-        is_clang = false
-        use_clang_coverage = false
-        current_os = "win"
-        current_cpu = rust_host_toolchain_arch
-      }
-    }
-    msvc_system_allocator_toolchain(
-        cl_toolchain_prefix + target_name + "_with_system_allocator") {
-      environment = "environment." + toolchain_arch
-      cl = "\"${win_toolchain_data.vc_bin_dir}/cl.exe\""
-
-      toolchain_args = {
-        if (defined(invoker.toolchain_args)) {
-          forward_variables_from(invoker.toolchain_args, "*")
-        }
-        is_clang = false
-        use_clang_coverage = false
-        current_os = "win"
-        current_cpu = toolchain_arch
-      }
-    }
-    msvc_rust_host_build_tools_toolchain(
-        cl_toolchain_prefix + target_name + "_for_rust_host_build_tools") {
+    msvc_rust_host_build_tools_toolchain(cl_toolchain_prefix + target_name) {
       environment = "environment." + rust_host_toolchain_arch
       cl = "\"${rust_host_win_toolchain_data.vc_bin_dir}/cl.exe\""
 
@@ -802,48 +736,7 @@
       current_cpu = toolchain_arch
     }
   }
-  msvc_system_allocator_toolchain(
-      clang_toolchain_prefix + target_name + "_host_with_system_allocator") {
-    environment = "environment." + rust_host_toolchain_arch
-    cl = "${_clang_bin_path}/clang-cl${_exe}"
-
-    sys_include_flags = "${rust_host_win_toolchain_data.include_flags_imsvc}"
-    if (use_lld) {
-      sys_lib_flags = "-libpath:$_clang_lib_dir " +
-                      "${rust_host_win_toolchain_data.libpath_lldlink_flags}"
-    }
-
-    toolchain_args = {
-      if (defined(invoker.toolchain_args)) {
-        forward_variables_from(invoker.toolchain_args, "*")
-      }
-      is_clang = true
-      current_os = "win"
-      current_cpu = rust_host_toolchain_arch
-    }
-  }
-  msvc_system_allocator_toolchain(
-      clang_toolchain_prefix + target_name + "_with_system_allocator") {
-    environment = "environment." + toolchain_arch
-    cl = "${_clang_bin_path}/clang-cl${_exe}"
-
-    sys_include_flags = "${win_toolchain_data.include_flags_imsvc}"
-    if (use_lld) {
-      sys_lib_flags = "-libpath:$_clang_lib_dir " +
-                      "${win_toolchain_data.libpath_lldlink_flags}"
-    }
-
-    toolchain_args = {
-      if (defined(invoker.toolchain_args)) {
-        forward_variables_from(invoker.toolchain_args, "*")
-      }
-      is_clang = true
-      current_os = "win"
-      current_cpu = toolchain_arch
-    }
-  }
-  msvc_rust_host_build_tools_toolchain(
-      clang_toolchain_prefix + target_name + "_for_rust_host_build_tools") {
+  msvc_rust_host_build_tools_toolchain(clang_toolchain_prefix + target_name) {
     environment = "environment." + rust_host_toolchain_arch
     cl = "${_clang_bin_path}/clang-cl${_exe}"
 
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index ff2df5e0..6c30be7 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1317,8 +1317,7 @@
       outputs =
           [ "$root_out_dir/{{source_file_part}}-$chrome_version_full.breakpad" ]
 
-      dump_syms =
-          "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)"
+      dump_syms = "//third_party/breakpad:dump_syms($host_toolchain)"
       args = rebase_path(outputs, root_build_dir) + [
                rebase_path(get_label_info(dump_syms, "root_out_dir") + "/" +
                                get_label_info(dump_syms, "name"),
diff --git a/chrome/updater/mac/BUILD.gn b/chrome/updater/mac/BUILD.gn
index ec4c538..0b4f9ed 100644
--- a/chrome/updater/mac/BUILD.gn
+++ b/chrome/updater/mac/BUILD.gn
@@ -537,8 +537,7 @@
   action_foreach("syms") {
     script = "//build/redirect_stdout.py"
     sources = _symbols_sources
-    dump_syms =
-        "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)"
+    dump_syms = "//third_party/breakpad:dump_syms($host_toolchain)"
     public_deps = [
       ":updater_bundle",
       dump_syms,
diff --git a/ios/BUILD.gn b/ios/BUILD.gn
index e32b1c8..8fadc0bc 100644
--- a/ios/BUILD.gn
+++ b/ios/BUILD.gn
@@ -43,5 +43,8 @@
     deps = []
   }
 
+  # Force dependency on symupload needed by official builder.
+  deps += [ "//third_party/breakpad:symupload" ]
+
   deps += [ "//ios/intents/app:intents" ]
 }
diff --git a/native_client_sdk/src/BUILD.gn b/native_client_sdk/src/BUILD.gn
index cc1e68f..ee813b1e 100644
--- a/native_client_sdk/src/BUILD.gn
+++ b/native_client_sdk/src/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/toolchain/toolchain.gni")
 import("//components/nacl/features.gni")
 
 declare_args() {
@@ -54,9 +53,9 @@
     # http://crbug.com/245456
     if (!is_win && target_cpu == "x64") {
       deps += [
-        "//third_party/breakpad:dump_syms($host_system_allocator_toolchain)",
-        "//third_party/breakpad:minidump_dump($host_system_allocator_toolchain)",
-        "//third_party/breakpad:minidump_stackwalk($host_system_allocator_toolchain)",
+        "//third_party/breakpad:dump_syms($host_toolchain)",
+        "//third_party/breakpad:minidump_dump($host_toolchain)",
+        "//third_party/breakpad:minidump_stackwalk($host_toolchain)",
       ]
     }
   }
diff --git a/third_party/breakpad/BUILD.gn b/third_party/breakpad/BUILD.gn
index 6fa55f7a..5fab2687 100644
--- a/third_party/breakpad/BUILD.gn
+++ b/third_party/breakpad/BUILD.gn
@@ -5,7 +5,6 @@
 import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/rust.gni")
 import("//build/symlink.gni")
-import("//build/toolchain/toolchain.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 import("//testing/test.gni")
 
@@ -13,90 +12,6 @@
   import("//build/config/win/visual_studio_version.gni")
 }
 
-# Breakpad executables are only built with the system allocator toolchains,
-# because when built with PartitionAlloc-Everywhere enabled, we see that they
-# OOM and crash: https://crbug.com/345514993.
-#
-# IMPORTANT: The executables here may almost all be built for the *host*
-# machine, not the target machine. However they are still built into the
-# root_build_dir where normally you'd find the outputs of the default_toolchain
-# which are meant to run on the *target* machine. This is quite abnormal, but
-# our GN dependencies and test scripts expect the binary to be in the
-# root_build_dir, and expect to run it on the host machine any time the tests
-# are run in a VM or on a device (such as IOS, Android, and ChromeOS). In other
-# cases, where the test launcher is the same as the target (such as any desktop
-# platform), we expect to run it on the target machine.
-#
-# As such, if the executables are built for the default toolchain, they will be
-# built with the host or the default toolchain's settings depending on if we
-# expect the tests to be launched from the target machine or from a host
-# machine. Then they are copied up to the `root_out_dir` of the
-# `default_toolchain.
-#
-# TODO(danakj): There is no support for building these on host A, launching
-# tests on host B, and running tests on target C, where A and B are different
-# machine types. This may become a problem on iOS for blink_web_tests, as on iOS
-# we may build on x86, upload/launch tests from arm64, and run tests on iOS
-# device. In that case, the host_toolchain is x86-mac, the default_toolchain
-# arm64-ios. But there's a third arm64-mac toolchain which
-# _tests_launcher_toolchain should point at, but it's not clear what that is
-# called in GN. It's not the default or the host toolchain. One possibility to
-# support this would be to make the host_system_allocator_toolchain build a
-# multi architecture binary that supports both arm64 and x64 and treat the host
-# as the test-launcher machine for iOS.
-#
-# IMPORTANT ALSO: symupload is different and special. This particular binary is
-# run by official build bots after compiling. It is always run on the host
-# machine, not the test-launcher machine. The official bots build and run
-# `symupload` in the default toolchain, so that binary must redirect from the
-# default toolchain to the *host* and not to the test laucher.
-#
-# TODO(danakj): It would be nice to move the host-targeting `symupload` to a
-# different directory that still remains fixed. Maybe something like
-# `out/Release/host/symupload`. But that will require:
-# - building it into both places temporarily
-# - updating a bunch of scripts in internal repositories.
-# - remove it from the default toolchain's outdir.
-if (is_ios || is_android || is_chromeos ||
-    # The breakpad exes do not compile successfully for Windows ARM.
-    (is_win && (current_cpu == "arm" || current_cpu == "arm64"))) {
-  # We build Windows ARM executables as Windows x64, targeting the host machine
-  # because they will run on the Arm machine still (through emulation) and
-  # because the code does not compile when targeting Windows ARM. This doesn't
-  # work for other hosts obviously.
-  assert(!is_win || host_os == "win")
-  _tests_launcher_toolchain = host_system_allocator_toolchain
-  _tests_launcher_toolchain_has_exe_suffix = host_os == "win"
-  _symupload_toolchain = host_system_allocator_toolchain
-  _symupload_toolchain_has_exe_suffix = host_os == "win"
-} else {
-  _tests_launcher_toolchain = default_system_allocator_toolchain
-  _tests_launcher_toolchain_has_exe_suffix = current_os == "win"
-  _symupload_toolchain = host_system_allocator_toolchain
-  _symupload_toolchain_has_exe_suffix = host_os == "win"
-}
-
-# Copies an executable target to the root directory of the current toolchain.
-# Used to copy from another toolchain. This requires that the executable is
-# built without component build enabled (see comment in //build/symlink.gni),
-# which is true for the `host_system_allocator_toolchain` and
-# `default_system_allocator_toolchain` toolchains in order to support this use
-# case.
-template("copy_exe") {
-  copy(target_name) {
-    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "public_deps" ])
-    public_deps = [ invoker.target ]
-    if (invoker.has_exe_suffix) {
-      _exe = ".exe"
-    } else {
-      _exe = ""
-    }
-    sources = [ get_label_info(invoker.target, "root_out_dir") + "/" +
-                get_label_info(invoker.target, "name") + _exe ]
-    outputs = [ "$root_out_dir/{{source_file_part}}" ]
-  }
-}
-
 config("tools_config") {
   include_dirs = [
     "breakpad/src",
@@ -165,8 +80,7 @@
 # {micro,mini}dump_stackwalk and minidump_dump are tool-type executables
 # that do not build on Windows.
 if (!is_win) {
-  if (current_toolchain == host_system_allocator_toolchain ||
-      current_toolchain == default_system_allocator_toolchain) {
+  if (current_toolchain == host_toolchain || target_os == "mac") {
     # Contains the code shared by both {micro,mini}dump_stackwalk.
     static_library("stackwalk_common") {
       # Binaries that use this library are not debugged frequently and
@@ -382,27 +296,16 @@
       configs -= [ "//build/config/compiler:chromium_code" ]
       configs += [ "//build/config/compiler:no_chromium_code" ]
     }
-  } else if (current_toolchain == default_toolchain) {
-    # The default toolchain builds the system-allocator binaries, which are
-    # placed in the output dir of the default toolchain.
-    copy_exe("microdump_stackwalk") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
+  } else {
+    # Aliases for convenience.
+    binary_symlink("microdump_stackwalk") {
+      binary_label = ":$target_name($host_toolchain)"
     }
-    copy_exe("minidump_stackwalk") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
+    binary_symlink("minidump_stackwalk") {
+      binary_label = ":$target_name($host_toolchain)"
     }
-    copy_exe("minidump_dump") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
-    if (use_centipede || use_libfuzzer) {
-      copy_exe("minidump_fuzzer") {
-        testonly = true
-        has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-        target = ":$target_name($_tests_launcher_toolchain)"
-      }
+    binary_symlink("minidump_dump") {
+      binary_label = ":$target_name($host_toolchain)"
     }
   }
 }
@@ -410,8 +313,7 @@
 # Mac --------------------------------------------------------------------------
 
 if (is_mac) {
-  if (current_toolchain == host_system_allocator_toolchain ||
-      current_toolchain == default_system_allocator_toolchain) {
+  if (current_toolchain == host_toolchain || target_os != "ios") {
     source_set("common") {
       sources = [
         "breakpad/src/common/dwarf/bytereader.cc",
@@ -550,53 +452,27 @@
              ] + [ "-go_src" ] + rebase_path(_go_sources, root_build_dir) +
              [ "-extra" ] + rebase_path(_extra_sources, root_build_dir)
     }
-  } else if (current_toolchain == default_toolchain) {
-    # The default toolchain builds the system-allocator binaries, which are
-    # placed in the output dir of the default toolchain.
-    copy_exe("dump_syms") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
+  } else {
+    binary_symlink("dump_syms") {
+      binary_label = ":$target_name($host_toolchain)"
     }
-    copy_exe("symupload") {
-      has_exe_suffix = _symupload_toolchain_has_exe_suffix
-      target = ":$target_name($_symupload_toolchain)"
-    }
-  } else if (current_toolchain == host_toolchain && current_cpu == "arm64") {
-    # TODO(crbug.com/349268750): This alias exists because the official Mac
-    # arm64 builders (which cross-build the x64 binaries) use the hardcoded
-    # path of the `$host_toolchain/symupload` to build and run the symupload
-    # binary. And the same recipes are used on all branches!! So we would break
-    # the stable branch builders by changing the recipe to build and run the
-    # binary from the root_build_dir.
-    #
-    # Once this code is in stable, we can land the following CLs to change how
-    # symupload is built and run on Mac arm64 official builders, and then this
-    # alias can be removed.
-    # Build: https://chrome-internal-review.googlesource.com/c/chrome/src-internal/+/7430844
-    # Run: https://chrome-internal-review.googlesource.com/c/chrome/tools/release/scripts/+/7430843
-    copy_exe("symupload") {
-      has_exe_suffix = _symupload_toolchain_has_exe_suffix
-      target = ":$target_name($_symupload_toolchain)"
+    binary_symlink("symupload") {
+      binary_label = ":$target_name($host_toolchain)"
     }
   }
 }
 
 if (is_ios) {
-  if (current_toolchain == default_toolchain) {
-    copy_exe("dump_syms") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
-    copy_exe("symupload") {
-      has_exe_suffix = _symupload_toolchain_has_exe_suffix
-      target = ":$target_name($_symupload_toolchain)"
-    }
+  binary_symlink("dump_syms") {
+    binary_label = ":$target_name($host_toolchain)"
+  }
+  binary_symlink("symupload") {
+    binary_label = ":$target_name($host_toolchain)"
   }
 }
 
 if (is_linux || is_chromeos || is_android) {
-  if (current_toolchain == host_system_allocator_toolchain ||
-      current_toolchain == default_system_allocator_toolchain) {
+  if (current_toolchain == host_toolchain) {
     executable("symupload") {
       sources = [
         "breakpad/src/common/linux/http_upload.cc",
@@ -697,16 +573,13 @@
 
       libs = [ "z" ]
     }
-  } else if (current_toolchain == default_toolchain) {
-    # The default toolchain builds the system-allocator binaries, which are
-    # placed in the output dir of the default toolchain.
-    copy_exe("dump_syms") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
+  } else {
+    # Aliases for convenience.
+    binary_symlink("dump_syms") {
+      binary_label = ":dump_syms($host_toolchain)"
     }
-    copy_exe("symupload") {
-      has_exe_suffix = _symupload_toolchain_has_exe_suffix
-      target = ":$target_name($_symupload_toolchain)"
+    binary_symlink("symupload") {
+      binary_label = ":symupload($host_toolchain)"
     }
   }
 
@@ -897,94 +770,85 @@
     configs += [ ":breakpad_unittest_config" ]
   }
 
-  if (current_toolchain == host_system_allocator_toolchain ||
-      current_toolchain == default_system_allocator_toolchain) {
-    executable("linux_dumper_unittest_helper") {
-      testonly = true
-      sources = [ "breakpad/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc" ]
-      deps = [ ":processor_support" ]
+  executable("linux_dumper_unittest_helper") {
+    testonly = true
+    sources = [ "breakpad/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc" ]
+    deps = [ ":processor_support" ]
 
-      configs += [ ":client_config" ]
+    configs += [ ":client_config" ]
 
-      if (is_component_build) {
-        ldflags = [ "-Wl,-rpath,\$ORIGIN" ]
-      }
+    if (is_component_build) {
+      ldflags = [ "-Wl,-rpath,\$ORIGIN" ]
     }
+  }
 
-    executable("generate_test_dump") {
-      testonly = true
-      sources = [ "linux/generate-test-dump.cc" ]
+  executable("generate_test_dump") {
+    testonly = true
+    sources = [ "linux/generate-test-dump.cc" ]
 
-      # This file has an unused variable warning.
-      configs -= [ "//build/config/compiler:chromium_code" ]
-      configs += [
-        ":client_config",
-        "//build/config/compiler:no_chromium_code",
-      ]
+    # This file has an unused variable warning.
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [
+      ":client_config",
+      "//build/config/compiler:no_chromium_code",
+    ]
 
-      deps = [ ":client" ]
+    deps = [ ":client" ]
 
-      if (is_android) {
-        libs = [ "log" ]
-      }
+    if (is_android) {
+      libs = [ "log" ]
     }
+  }
 
-    executable("minidump-2-core") {
-      sources = [
-        "breakpad/src/common/path_helper.cc",
-        "breakpad/src/common/path_helper.h",
-        "breakpad/src/tools/linux/md2core/minidump-2-core.cc",
-        "breakpad/src/tools/linux/md2core/minidump_memory_range.h",
-      ]
+  executable("minidump-2-core") {
+    sources = [
+      "breakpad/src/common/path_helper.cc",
+      "breakpad/src/common/path_helper.h",
+      "breakpad/src/tools/linux/md2core/minidump-2-core.cc",
+      "breakpad/src/tools/linux/md2core/minidump_memory_range.h",
+    ]
 
-      include_dirs = [ "breakpad/src" ]
+    include_dirs = [ "breakpad/src" ]
 
-      deps = [ ":client" ]
-    }
+    deps = [ ":client" ]
+  }
 
-    executable("core-2-minidump") {
-      sources = [
-        "breakpad/src/common/path_helper.cc",
-        "breakpad/src/common/path_helper.h",
-        "breakpad/src/tools/linux/core2md/core2md.cc",
-      ]
+  executable("core-2-minidump") {
+    sources = [
+      "breakpad/src/common/path_helper.cc",
+      "breakpad/src/common/path_helper.h",
+      "breakpad/src/tools/linux/core2md/core2md.cc",
+    ]
 
-      deps = [ ":client" ]
+    deps = [ ":client" ]
 
-      include_dirs = [ "breakpad/src" ]
-    }
-  } else if (current_toolchain == default_toolchain) {
-    # The default toolchain builds the system-allocator binaries, which are
-    # linked from the output dir of the default toolchain.
-
-    # Most breakpad binaries are only built for the `_tests_launcher_toolchain`.
-    # This is different, as it's used _inside_ a test, and thus needs to be
-    # built for the target machine, not the test-launcher machine.
-    copy_exe("linux_dumper_unittest_helper") {
-      testonly = true
-      has_exe_suffix = false
-      target = ":$target_name($default_system_allocator_toolchain)"
-    }
-
-    copy_exe("generate_test_dump") {
-      testonly = true
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
-    copy_exe("minidump-2-core") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
-    copy_exe("core-2-minidump") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
+    include_dirs = [ "breakpad/src" ]
   }
 }
 
 if (is_win) {
-  if (current_toolchain == host_system_allocator_toolchain ||
-      current_toolchain == default_system_allocator_toolchain) {
+  # Force a native symupload, since Chrome tries to be "helpful" and not really
+  # differentiate target vs. host for x86/x64 builds.
+  #
+  # Normally, this would just use the (current_toolchain == host_toolchain)
+  # condition, which would cause these targets to only be compiled for the host
+  # CPU (i.e. to only build "native" binaries), but the Chrome Windows build
+  # will "always use the target CPU for host builds for x86/x64":
+  # https://crrev.com/3258ed4d9d755a3564d98bef8707bbdb5f8a7974/config/BUILDCONFIG.gn#199
+  # This means that host_toolchain will be x86 (32-bit) if the target is x86,
+  # even when the host is actually x64 (64-bit), which causes this to create
+  # 32-bit binaries, despite wanting native, 64-bit binaries.
+  #
+  # Adding the second condition enables this block for the "true" host
+  # toolchain as well, which allows creating 64-bit binaries even when the host
+  # toolchain is redefined to a 32-bit target.
+  if (is_clang) {
+    symupload_toolchain = "//build/toolchain/win:win_clang_$host_cpu"
+  } else {
+    symupload_toolchain = "//build/toolchain/win:$host_cpu"
+  }
+  if (current_toolchain == host_toolchain ||
+      current_toolchain == symupload_toolchain) {
     static_library("common_windows") {
       include_dirs = [
         "$visual_studio_path/DIA SDK/include",
@@ -1062,14 +926,38 @@
       }
     }
 
-    executable("symupload") {
+    group("symupload") {
+      deps = [ ":symupload_win($symupload_toolchain)" ]
+    }
+    executable("symupload_win") {
       include_dirs = [
         "$visual_studio_path/DIA SDK/include",
         "breakpad/src",
       ]
+      output_name = "symupload"
+
+      # Invert the normal logic which puts binaries built with the default
+      # (target) toolchain into the root output directory, and other toolchain
+      # binaries into subdirs. This gives preference to the native symupload,
+      # which is what's wanted in most situations. The cross-compiled binary
+      # can still be created (by building "symupload_win" instead of
+      # "symupload") and found in the corresponding toolchain subdir (e.g.
+      # //out/Release/win_clang_x86/ when cross-compiling to x86).
+      if (current_toolchain == symupload_toolchain) {
+        output_dir = "$root_build_dir"
+      } else {
+        output_name = "symupload_$target_cpu"
+        toolchain_parts =
+            string_split(get_path_info(current_toolchain, "name"), ":")
+        output_dir = "$root_out_dir/" + toolchain_parts[1]
+      }
+
       sources = [ "breakpad/src/tools/windows/symupload/symupload.cc" ]
+
       deps = [ "//third_party/breakpad:common_windows" ]
+
       ldflags = [ "/LARGEADDRESSAWARE" ]
+
       lib_dirs = []
       if (current_cpu == "x64") {
         lib_dirs += [ "$visual_studio_path/DIA SDK/lib/amd64" ]
@@ -1134,21 +1022,9 @@
         cflags = [ "-Wno-microsoft-goto" ]
       }
     }
-  } else if (current_toolchain == default_toolchain) {
-    # The default toolchain builds the system-allocator binaries, which are
-    # placed in the output dir of the default toolchain.
-    copy_exe("google_converter") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
-    copy_exe("symupload") {
-      has_exe_suffix = _symupload_toolchain_has_exe_suffix
-      target = ":$target_name($_symupload_toolchain)"
-    }
-    copy_exe("dump_syms") {
-      has_exe_suffix = _tests_launcher_toolchain_has_exe_suffix
-      target = ":$target_name($_tests_launcher_toolchain)"
-    }
+  } else {
+    # handle dump_syms appropriately for Windows cross build when necessary,
+    # such as symlinking.
   }
 }
 
diff --git a/tools/perf/chrome_telemetry_build/BUILD.gn b/tools/perf/chrome_telemetry_build/BUILD.gn
index 760386e..8a33f5dc 100644
--- a/tools/perf/chrome_telemetry_build/BUILD.gn
+++ b/tools/perf/chrome_telemetry_build/BUILD.gn
@@ -48,7 +48,7 @@
   }
 
   if (is_linux || is_chromeos) {
-    data_deps += [ "//third_party/breakpad:dump_syms" ]
+    data_deps += [ "//third_party/breakpad:dump_syms($host_toolchain)" ]
 
     # CrOS currently has issues with the locally compiled version of
     # crashpad_database_util, so only include it on traditional Linux