Internal change

PiperOrigin-RevId: 455614618
diff --git a/BUILD b/BUILD
index 41af84a..9e7795f 100644
--- a/BUILD
+++ b/BUILD
@@ -294,6 +294,15 @@
     ],
 )
 
+cc_library(
+    name = "weak_sancov_stubs",
+    srcs = ["weak_sancov_stubs.cc"],
+    deps = [
+        "//third_party/tcmalloc",
+    ],
+    alwayslink = 1,
+)
+
 # runner_fork_server can be linked to a binary or used directly as a .so via LD_PRELOAD.
 cc_library(
     name = "runner_fork_server",
diff --git a/testing/BUILD b/testing/BUILD
index 6036df4..ff9b73b 100644
--- a/testing/BUILD
+++ b/testing/BUILD
@@ -79,6 +79,19 @@
     sancov = "trace-pc",
 )
 
+# Empty fuzz target for testing weak_sancov_stubs.
+centipede_test_target(
+    name = "empty_fuzz_target",
+    data = [
+        "//third_party/centipede",
+    ],
+)
+
+centipede_test_target_sancov(
+    name = "empty_fuzz_target_sancov",
+    fuzz_target = "empty_fuzz_target",
+)
+
 # TODO(ussuri): [impl] move this and all other
 #  cc_fuzz_target/centipede_test_target_sancov into a separate subdir, and
 #  simplify the BUILD syntax, so that adding more test targets is easier.
@@ -229,6 +242,7 @@
     srcs = ["centipede_test.cc"],
     data = [
         ":abort_fuzz_target_sancov",
+        ":empty_fuzz_target_sancov",
         ":test_fuzz_target_sancov",
         ":test_input_filter",
     ],
@@ -255,6 +269,7 @@
     srcs = ["centipede_main_test.sh"],
     data = [
         ":abort_fuzz_target_sancov",
+        ":empty_fuzz_target_sancov",
         ":target_example",
         ":test_fuzz_target_sancov",
         "//third_party/centipede",
diff --git a/testing/build_defs.bzl b/testing/build_defs.bzl
index da32367..7e96b91 100644
--- a/testing/build_defs.bzl
+++ b/testing/build_defs.bzl
@@ -51,7 +51,7 @@
         ],
         # Disable tcmalloc to avoid coverage features from it.
         "//command_line_option:compilation_mode": "opt",
-        "//command_line_option:custom_malloc": "//base:system_malloc",
+        "//command_line_option:custom_malloc": "//third_party/centipede:weak_sancov_stubs",
         "//security/fuzzing/bazel:fuzzing_engine": "centipede",
         "//command_line_option:strip": "never",  # preserve debug info.
         "//command_line_option:features": filtered_features,
@@ -88,10 +88,14 @@
         command = "cp %s %s" % (executable_src.path, executable_dst.path),
     )
 
-    # See https://docs.bazel.build/versions/master/skylark/lib/DefaultInfo.html
-    runfiles = ctx.runfiles(
-        collect_data = True,
-    )
+    # We need to explicitly collect the runfiles from all relevant attributes.
+    # See https://docs.bazel.build/versions/main/skylark/rules.html#runfiles
+    runfiles = ctx.runfiles()
+
+    # The transition transforms scalar attributes into lists,
+    # so we need to index into the list first.
+    fuzz_target = ctx.attr.fuzz_target[0]
+    runfiles = runfiles.merge(fuzz_target[DefaultInfo].default_runfiles)
     return [DefaultInfo(runfiles = runfiles, executable = executable_dst)]
 
 __sancov_fuzz_target = rule(
@@ -135,10 +139,11 @@
         sancov = sancov,
     )
 
-def centipede_test_target(name):
+def centipede_test_target(name, data = None):
     cc_fuzz_target(
         name = name,
         srcs = [name + ".cc"],
+        data = data or [],
         componentid = 1187448,  #Language Platforms > Sanitizers > Centipede
         tags = [
             # Don't test this fuzz target on TAP or autofuzz,
diff --git a/testing/empty_fuzz_target.cc b/testing/empty_fuzz_target.cc
new file mode 100644
index 0000000..8ac3708
--- /dev/null
+++ b/testing/empty_fuzz_target.cc
@@ -0,0 +1,23 @@
+// Copyright 2022 The Centipede Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// A simple fuzz target for testing successfully building with
+// weak_sancov_stubs.
+
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  return 0;
+}
diff --git a/weak_sancov_stubs.cc b/weak_sancov_stubs.cc
new file mode 100644
index 0000000..525714c
--- /dev/null
+++ b/weak_sancov_stubs.cc
@@ -0,0 +1,42 @@
+// Copyright 2022 The Centipede Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#define WEAK_SANCOV_DEF(ReturnType, Name, ...) \
+  extern "C" __attribute__((weak)) \
+  ReturnType Name(__VA_ARGS__)
+
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_cmp, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_cmp1, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_cmp2, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_cmp4, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_cmp8, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_const_cmp1, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_const_cmp2, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_const_cmp4, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_const_cmp8, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_switch, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_div4, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_div8, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_gep, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_8bit_counters_init, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_bool_flag_init, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_pcs_init, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_pc_guard, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_trace_pc_guard_init, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_load1, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_load2, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_load4, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_load8, void) {}
+WEAK_SANCOV_DEF(void, __sanitizer_cov_load16, void) {}