blob: f23f68b1a98f4158c1319d65e8c13de6d324c42f [file] [log] [blame]
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/zircon/levels.gni")
import("../libc.gni")
group("scudo") {
if (!variant_replaces_allocator) {
# If we are using a sanitizer that replaces the allocator, do not include
# scudo in libc so we can use the sanitizer allocator. Stubs are provided
# that replace scudo's definitions.
deps = [ ":scudo-allocator" ]
}
}
scudo_common_vars = {
dir = scudo
include_dirs = [
".",
dir,
"$dir/include",
# The gwp_asan code uses #include "gwp_asan/...".
"${gwp_asan}/..",
]
configs = [ ":common.config" ]
deps = [
"//src/zircon/lib/zircon",
"//zircon/system/ulib/sync",
]
}
libc_source_set("scudo-allocator") {
forward_variables_from(scudo_common_vars, "*")
sources = [
"checksum.cpp",
"common.cpp",
"crc32_hw.cpp",
"flags.cpp",
"flags_parser.cpp",
"fuchsia.cpp",
"linux.cpp",
"mem_map.cpp",
"mem_map_fuchsia.cpp",
"release.cpp",
"report.cpp",
"string_utils.cpp",
"timing.cpp",
]
# The code needs to be compiled separately for production and test use for
# two reasons.
#
# The first reason only affects the flag-parsing code (src/flags.cpp): it
# uses the `__scudo_default_options` callback function. The test code wants
# to define this to set special options needed by certain tests. But
# defining it by that name will also affect the production Scudo built into
# libc, which the test should not do (and it makes it very hard to e.g. debug
# the test linked against a libc containing a slightly different version of
# Scudo than the code under test). So both the flag-parsing code and the
# test code must be compiled with `-D__scudo_default_options=<some other
# name>` to make the test code safe.
#
# TODO(https://fxbug.dev/42142757): The second reason is similar but more subtle and it
# affects much of the code, both the Scudo code proper and the gwp_asan code
# it incorporates. These both use thread-local state that is directly
# located in the thread structure when the code is built into libc, because
# normal `thread_local` C++ variables are not available inside libc itself
# (due to implementation constraints in the dynamic linker). If the test
# code is built the same way, then it will clobber the thread-local state of
# the libc Scudo/gwp_asan code, which the test should not do.
non_test_deps = [
":gwp_asan",
":libc",
":wrappers",
]
testonly_deps = [
":gwp_asan.testonly",
":testonly",
]
}
config("common.config") {
visibility = [ ":*" ]
# This enables Scudo DCHECK* when ZX_DEBUG_ASSERT is enabled.
if (zx_assert_level > 1) {
scudo_debug = 1
} else {
scudo_debug = 0
}
defines = [
"GWP_ASAN_HOOKS=1",
"SCUDO_DEBUG=$scudo_debug",
"SCUDO_ENABLE_HOOKS=1",
"SCUDO_USE_CUSTOM_CONFIG=1",
# TODO(https://fxbug.dev/42082832): Scudo, which lives in the C library, cannot
# see the hooks defined by the wrapper-tests in the test executable.
"SCUDO_ENABLE_HOOKS_TESTS=0",
]
include_dirs = [ "." ]
}
# These define the public API entry points (malloc et al). They cannot be
# included in the test code without polluting the test harness and other
# unrelated code with the allocator code under test. So they are only
# included in libc itself, not in the test build.
libc_source_set("wrappers") {
forward_variables_from(scudo_common_vars, "*")
sources = [
"wrappers_c.cpp",
# TODO(https://fxbug.dev/42082846): Disable c++ wrappers provided by Scudo.
#"wrappers_cpp.cpp",
]
non_test_deps = [ ":libc" ]
}
group("libc") {
visibility = [ ":*" ]
public_configs = [ ":libc.config" ]
public_deps = [
# The local headers introduced by libc.config (below) use libc internals,
# so they need access to the internal headers.
"//zircon/third_party/ulib/musl:musl_internal",
]
}
config("libc.config") {
visibility = [ ":*" ]
defines = [
# Tell the scudo and gwp_asan code to use our headers.
"SCUDO_HAS_PLATFORM_TLS_SLOT=1",
"GWP_ASAN_PLATFORM_TLS_HEADER=<gwp_asan_platform_tls_slot.h>",
# GWP-ASan is opt-in via the SCUDO_OPTIONS environment variable.
"GWP_ASAN_DEFAULT_ENABLED=false",
]
# This library is linked into libc, which is used by libfuzzer.
# Don't instrument it to avoid getting noise in code coverage.
# TODO(https://fxbug.dev/42099340): Once a cleaner solution is found, remove this.
configs = [ "//build/config/zircon:no_fuzzer" ]
}
group("testonly") {
visibility = [ ":*" ]
public_configs = [ ":testonly.config" ]
}
config("testonly.config") {
visibility = [ ":*" ]
# TODO(crbug.com/gn/214): testonly = true
# The test version avoids that symbol name since it also affects the system
# libc and not only the code under test. Instead it renames the function to
# a safe name for the test. The test code that defines its own function by
# this name also uses this config so it renames its definition to match.
defines = [ "__scudo_default_options=testonly_scudo_default_options" ]
}
gwp_asan_common_vars = {
forward_variables_from(scudo_common_vars, "*")
dir = gwp_asan
}
libc_source_set("gwp_asan") {
forward_variables_from(gwp_asan_common_vars, "*")
sources = [
"guarded_pool_allocator.cpp",
"guarded_pool_allocator.h",
"mutex.h",
"optional/backtrace.h",
"optional/backtrace_fuchsia.cpp",
"optional/printf.h",
"optional/segv_handler.h",
"optional/segv_handler_fuchsia.cpp",
"platform_specific/guarded_pool_allocator_fuchsia.cpp",
"platform_specific/guarded_pool_allocator_fuchsia.h",
"platform_specific/guarded_pool_allocator_tls.h",
"platform_specific/mutex_fuchsia.cpp",
"platform_specific/mutex_fuchsia.h",
"platform_specific/utilities_fuchsia.cpp",
]
public_deps = [ ":gwp-asan-common" ]
non_test_deps = [
":gwp-asan-info",
":libc",
]
testonly_deps = [ ":testonly" ]
}
libc_source_set("gwp-asan-info") {
forward_variables_from(gwp_asan_common_vars, "*", [ "dir" ])
deps += [
":gwp-asan-common",
":libc",
]
sources = [
"gwp_asan_info.cc",
"gwp_asan_note.S",
]
}
# Crash handlers should depend on this target.
source_set("gwp-asan-common") {
public_configs = [ ":gwp-asan-common-config" ]
sources = [
"${gwp_asan}/common.cpp",
"${gwp_asan}/common.h",
"${gwp_asan}/crash_handler.cpp",
"${gwp_asan}/crash_handler.h",
"${gwp_asan}/definitions.h",
"${gwp_asan}/options.h",
"${gwp_asan}/platform_specific/common_fuchsia.cpp",
"${gwp_asan}/stack_trace_compressor.cpp",
"${gwp_asan}/stack_trace_compressor.h",
"gwp_asan_info.h",
]
}
config("gwp-asan-common-config") {
include_dirs = [ "${gwp_asan}/.." ]
}
# This is included in libc-unittests and standalone core-tests.
libc_test("unittests") {
forward_variables_from(scudo_common_vars, "*")
sources = [
"tests/atomic_test.cpp",
"tests/bytemap_test.cpp",
"tests/checksum_test.cpp",
"tests/chunk_test.cpp",
"tests/combined_test.cpp",
"tests/flags_test.cpp",
"tests/list_test.cpp",
"tests/map_test.cpp",
"tests/mutex_test.cpp",
"tests/primary_test.cpp",
"tests/quarantine_test.cpp",
"tests/release_test.cpp",
"tests/report_test.cpp",
"tests/scudo_unit_test_main.cpp",
"tests/secondary_test.cpp",
"tests/size_class_map_test.cpp",
"tests/stats_test.cpp",
"tests/strings_test.cpp",
"tests/timing_test.cpp",
"tests/tsd_test.cpp",
"tests/vector_test.cpp",
]
deps += [
":gwp_asan-unittests",
":scudo-allocator.testonly",
]
# The public API tests both assume Scudo's behavior rather than purely kosher
# standard behavior and they include testing error cases. The instrumented
# runtimes' allocators often make error cases or dubiously kosher uses fatal.
if (!variant_replaces_allocator) {
deps += [ ":wrapper-tests" ]
}
# Suppress warnings from third party code
configs += [ "//build/config:Wno-extra-semi" ]
}
# These tests use the public API, so they are testing what's actually in libc
# rather than the isolated test code.
libc_test("wrapper-tests") {
forward_variables_from(scudo_common_vars, "*")
sources = [
"tests/wrappers_c_test.cpp",
# TODO(https://fxbug.dev/42082846): see src/wrappers_cpp.cpp inclusion above.
#"tests/wrappers_cpp_test.cpp",
]
}
libc_test("gwp_asan-unittests") {
forward_variables_from(gwp_asan_common_vars, "*")
sources = [
"tests/alignment.cpp",
"tests/backtrace.cpp",
"tests/basic.cpp",
"tests/compression.cpp",
"tests/crash_handler_api.cpp",
# TODO(kostyak): fork() based, see if it can apply to Fuchsia
#"tests/enable_disable.cpp",
"tests/harness.cpp",
"tests/harness.h",
"tests/iterate.cpp",
# TODO(https://fxbug.dev/42144233): flaky due to TLS pollution
#"tests/late_init.cpp",
"tests/mutex_test.cpp",
"tests/never_allocated.cpp",
# Exclude because signal handlers used in recoverable tests are unsupported
#"tests/recoverable.cpp"
"tests/slot_reuse.cpp",
"tests/thread_contention.cpp",
]
deps += [
":gwp_asan.testonly",
":gwp_asan_test_printf",
]
# Suppress warnings from third party code
configs += [ "//build/config:Wno-extra-semi" ]
}
source_set("gwp_asan_test_printf") {
testonly = true
include_dirs = [ "${gwp_asan}/.." ]
deps = [ ":gwp_asan.testonly" ]
sources = [ "gwp_asan_test_printf.cc" ]
}